diff options
author | Pietro Abate <pietro.abate@pps.jussieu.fr> | 2009-02-16 08:47:51 +0000 |
---|---|---|
committer | Pietro Abate <pietro.abate@pps.jussieu.fr> | 2009-02-16 08:47:51 +0000 |
commit | bff8751fb4ecbacfaf57cabf53ecb385322c6df6 (patch) | |
tree | 021e8083b1c1cfdd6476751787ffdc5dea30a0eb /examples | |
parent | 954146cfc77e6b85719edc4fde60c3ecb1400b67 (diff) |
Imported Upstream version 0.6.1
Diffstat (limited to 'examples')
-rw-r--r-- | examples/README.txt | 1 | ||||
-rw-r--r-- | examples/adder/adder.ml | 2 | ||||
-rw-r--r-- | examples/genclient/genclient.ml | 94 | ||||
-rw-r--r-- | examples/ubigraph/Makefile | 7 | ||||
-rw-r--r-- | examples/ubigraph/OCamlMakefile | 1154 | ||||
-rw-r--r-- | examples/ubigraph/Ubigraph.ml | 169 | ||||
-rw-r--r-- | examples/ubigraph/Ubigraph.mli | 51 | ||||
-rw-r--r-- | examples/ubigraph/test.ml | 54 | ||||
-rw-r--r-- | examples/wordpress/WordPress.ml | 372 | ||||
-rw-r--r-- | examples/wordpress/WordPress.mli | 94 | ||||
-rw-r--r-- | examples/wordpress/test.ml | 2 |
11 files changed, 1962 insertions, 38 deletions
diff --git a/examples/README.txt b/examples/README.txt index 4037961..9ef0b22 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -5,4 +5,5 @@ Source code examples: - adder: simple XmlRpcServer example, adds two numbers - genclient: code generation tool using introspection methods + - ubigraph: bindings to Ubigraph visualization tool - wordpress: client interface for WordPress blog API diff --git a/examples/adder/adder.ml b/examples/adder/adder.ml index 8f84261..f717499 100644 --- a/examples/adder/adder.ml +++ b/examples/adder/adder.ml @@ -1,6 +1,6 @@ (* * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet - * Copyright (C) 2007 Dave Benjamin (dave@ramenlabs.com) + * Copyright (C) 2007-2009 Dave Benjamin (dave@ramenlabs.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/examples/genclient/genclient.ml b/examples/genclient/genclient.ml index cc2e79c..388335e 100644 --- a/examples/genclient/genclient.ml +++ b/examples/genclient/genclient.ml @@ -1,14 +1,39 @@ +(* + * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet + * Copyright (C) 2007-2008 Dave Benjamin (dave@ramenlabs.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + *) + open Printf module StringMap = Map.Make(String) +let url = ref "" + +let use_int32 = ref false +let use_multicall = ref false +let verbose = ref false + let variant_name = function | `String "array" -> Some "`Array" | `String "base64" -> Some "`Binary" | `String "boolean" -> Some "`Boolean" | `String "dateTime.iso8601" -> Some "`DateTime" | `String "double" -> Some "`Double" - | `String "int" -> Some "`Int" + | `String "int" -> Some (if !use_int32 then "`Int32" else "`Int") | `String "string" -> Some "`String" | `String "struct" -> Some "`Struct" | `String "undefined" -> None @@ -25,12 +50,15 @@ let dot_to_underscore s = s let () = - if Array.length Sys.argv < 2 - then (printf "Usage: %s url\n" Sys.argv.(0); exit 1) - else () + let specs = + ["-i", Arg.Set use_int32, "Use int32 for all integers"; + "-m", Arg.Set use_multicall, "Generate lazy interface using multicall"; + "-v", Arg.Set verbose, "Display verbose debugging output"] in + let usage = (sprintf "Usage: %s [-i] [-m] [-v] url" Sys.argv.(0)) in + Arg.parse specs (fun url' -> url := url') usage; + if !url = "" then (Arg.usage specs usage; exit 2) -let url = Sys.argv.(1) -let rpc = new XmlRpc.client url +let rpc = new XmlRpc.client ~debug:!verbose !url let methods = rpc#call "system.listMethods" [] @@ -111,32 +139,58 @@ let impl_with_signature module_name func_name name = | None -> sprintf "_%d" i) params)) in + let mc_init = + if !use_multicall + then "if mc#executed then mc <- new XmlRpc.multicall rpc;\n " + else "" in + let rpc_call = if !use_multicall then "mc#call" else "rpc#call" in + let begin_lazy_force, lazy_force, end_lazy_force = + if !use_multicall + then "lazy (", "Lazy.force ", ")" + else "", "", "" in (match variant_name result with | Some result_type -> sprintf " method %s %s = - match rpc#call \"%s.%s\" [%s] with + %slet result = %s \"%s.%s\" [%s] in + %smatch %sresult with | %s r -> r - | other -> raise (Type_error (XmlRpc.dump other))" + | other -> raise (Type_error (XmlRpc.dump other))%s" func_name (if param_names = "" then "()" else param_names) + mc_init + rpc_call module_name name param_values - result_type + begin_lazy_force + lazy_force + (if result_type = "`Int32" + then "`Int r -> Int32.of_int r | `Int32" + else result_type) + end_lazy_force | None -> sprintf " method %s %s = - rpc#call \"%s.%s\" [%s]" + %s%s \"%s.%s\" [%s]" func_name (if param_names = "" then "()" else param_names) + mc_init + rpc_call module_name name param_values) | _ -> failwith "method signature was not an array" let impl_without_signature module_name func_name name = + let mc_init = + if !use_multicall + then "if mc#executed then mc <- new XmlRpc.multicall rpc;\n " + else "" in + let rpc_call = if !use_multicall then "mc#call" else "rpc#call" in sprintf " method %s params = - rpc#call \"%s.%s\" params" + %s%s \"%s.%s\" params" func_name + mc_init + rpc_call module_name name @@ -185,9 +239,17 @@ let objects = (impls module_name meths)) module_map)) +let multicall = + if !use_multicall + then " + val mutable mc = new XmlRpc.multicall rpc + method mc = mc +" + else "" + let () = - printf "(* Automatically generated by running genclient with an - XML-RPC server located at the following URL: + printf "(* Automatically generated from an XML-RPC server + by running the following command: %s *) @@ -195,10 +257,10 @@ let () = exception Type_error of string class client url = + let rpc = new XmlRpc.client url in object (self) - val rpc = new XmlRpc.client url method rpc = rpc - +%s %s end -" url objects +" (String.concat " " (Array.to_list Sys.argv)) multicall objects diff --git a/examples/ubigraph/Makefile b/examples/ubigraph/Makefile new file mode 100644 index 0000000..fd29771 --- /dev/null +++ b/examples/ubigraph/Makefile @@ -0,0 +1,7 @@ +OCAMLMAKEFILE = OCamlMakefile + +RESULT = test +SOURCES = Ubigraph.mli Ubigraph.ml test.ml +PACKS = xmlrpc-light + +include $(OCAMLMAKEFILE) diff --git a/examples/ubigraph/OCamlMakefile b/examples/ubigraph/OCamlMakefile new file mode 100644 index 0000000..9adb295 --- /dev/null +++ b/examples/ubigraph/OCamlMakefile @@ -0,0 +1,1154 @@ +########################################################################### +# OCamlMakefile +# Copyright (C) 1999-2004 Markus Mottl +# +# For updates see: +# http://www.ocaml.info/home/ocaml_sources.html +# +# $Id: OCamlMakefile,v 1.72 2005/12/09 15:30:50 mottl Exp $ +# +########################################################################### + +# Modified by damien for .glade.ml compilation + +# Set these variables to the names of the sources to be processed and +# the result variable. Order matters during linkage! + +ifndef SOURCES + SOURCES := foo.ml +endif +export SOURCES + +ifndef RES_CLIB_SUF + RES_CLIB_SUF := _stubs +endif +export RES_CLIB_SUF + +ifndef RESULT + RESULT := foo +endif +export RESULT + +export LIB_PACK_NAME + +ifndef DOC_FILES + DOC_FILES := $(filter %.mli, $(SOURCES)) +endif +export DOC_FILES + +export BCSUFFIX +export NCSUFFIX + +ifndef TOPSUFFIX + TOPSUFFIX := .top +endif +export TOPSUFFIX + +# Eventually set include- and library-paths, libraries to link, +# additional compilation-, link- and ocamlyacc-flags +# Path- and library information needs not be written with "-I" and such... +# Define THREADS if you need it, otherwise leave it unset (same for +# USE_CAMLP4)! + +export THREADS +export VMTHREADS +export ANNOTATE +export USE_CAMLP4 + +export INCDIRS +export LIBDIRS +export EXTLIBDIRS +export RESULTDEPS +export OCAML_DEFAULT_DIRS + +export LIBS +export CLIBS + +export OCAMLFLAGS +export OCAMLNCFLAGS +export OCAMLBCFLAGS + +export OCAMLLDFLAGS +export OCAMLNLDFLAGS +export OCAMLBLDFLAGS + +ifndef OCAMLCPFLAGS + OCAMLCPFLAGS := a +endif + +export OCAMLCPFLAGS + +export PPFLAGS + +export YFLAGS +export IDLFLAGS + +export OCAMLDOCFLAGS + +export OCAMLFIND_INSTFLAGS + +export DVIPSFLAGS + +export STATIC + +# Add a list of optional trash files that should be deleted by "make clean" +export TRASH + +#################### variables depending on your OCaml-installation + +ifdef MINGW + export MINGW + WIN32 := 1 + CFLAGS_WIN32 := -mno-cygwin +endif +ifdef MSVC + export MSVC + WIN32 := 1 + ifndef STATIC + CPPFLAGS_WIN32 := -DCAML_DLL + endif + CFLAGS_WIN32 += -nologo + EXT_OBJ := obj + EXT_LIB := lib + ifeq ($(CC),gcc) + # work around GNU Make default value + ifdef THREADS + CC := cl -MT + else + CC := cl + endif + endif + ifeq ($(CXX),g++) + # work around GNU Make default value + CXX := $(CC) + endif + CFLAG_O := -Fo +endif +ifdef WIN32 + EXT_CXX := cpp + EXE := .exe +endif + +ifndef EXT_OBJ + EXT_OBJ := o +endif +ifndef EXT_LIB + EXT_LIB := a +endif +ifndef EXT_CXX + EXT_CXX := cc +endif +ifndef EXE + EXE := # empty +endif +ifndef CFLAG_O + CFLAG_O := -o # do not delete this comment (preserves trailing whitespace)! +endif + +export CC +export CXX +export CFLAGS +export CXXFLAGS +export LDFLAGS +export CPPFLAGS + +ifndef RPATH_FLAG + RPATH_FLAG := -R +endif +export RPATH_FLAG + +ifndef MSVC +ifndef PIC_CFLAGS + PIC_CFLAGS := -fPIC +endif +ifndef PIC_CPPFLAGS + PIC_CPPFLAGS := -DPIC +endif +endif + +export PIC_CFLAGS +export PIC_CPPFLAGS + +BCRESULT := $(addsuffix $(BCSUFFIX), $(RESULT)) +NCRESULT := $(addsuffix $(NCSUFFIX), $(RESULT)) +TOPRESULT := $(addsuffix $(TOPSUFFIX), $(RESULT)) + +ifndef OCAMLFIND + OCAMLFIND := ocamlfind +endif +export OCAMLFIND + +ifndef OCAMLC + OCAMLC := ocamlc +endif +export OCAMLC + +ifndef OCAMLOPT + OCAMLOPT := ocamlopt +endif +export OCAMLOPT + +ifndef OCAMLMKTOP + OCAMLMKTOP := ocamlmktop +endif +export OCAMLMKTOP + +ifndef OCAMLCP + OCAMLCP := ocamlcp +endif +export OCAMLCP + +ifndef OCAMLDEP + OCAMLDEP := ocamldep +endif +export OCAMLDEP + +ifndef OCAMLLEX + OCAMLLEX := ocamllex +endif +export OCAMLLEX + +ifndef OCAMLYACC + OCAMLYACC := ocamlyacc +endif +export OCAMLYACC + +ifndef OCAMLMKLIB + OCAMLMKLIB := ocamlmklib +endif +export OCAMLMKLIB + +ifndef OCAML_GLADECC + OCAML_GLADECC := lablgladecc2 +endif +export OCAML_GLADECC + +ifndef OCAML_GLADECC_FLAGS + OCAML_GLADECC_FLAGS := +endif +export OCAML_GLADECC_FLAGS + +ifndef CAMELEON_REPORT + CAMELEON_REPORT := report +endif +export CAMELEON_REPORT + +ifndef CAMELEON_REPORT_FLAGS + CAMELEON_REPORT_FLAGS := +endif +export CAMELEON_REPORT_FLAGS + +ifndef CAMELEON_ZOGGY + CAMELEON_ZOGGY := camlp4o pa_zog.cma pr_o.cmo +endif +export CAMELEON_ZOGGY + +ifndef CAMELEON_ZOGGY_FLAGS + CAMELEON_ZOGGY_FLAGS := +endif +export CAMELEON_ZOGGY_FLAGS + +ifndef OXRIDL + OXRIDL := oxridl +endif +export OXRIDL + +ifndef CAMLIDL + CAMLIDL := camlidl +endif +export CAMLIDL + +ifndef CAMLIDLDLL + CAMLIDLDLL := camlidldll +endif +export CAMLIDLDLL + +ifndef NOIDLHEADER + MAYBE_IDL_HEADER := -header +endif +export NOIDLHEADER + +export NO_CUSTOM + +ifndef CAMLP4 + CAMLP4 := camlp4 +endif +export CAMLP4 + +ifndef REAL_OCAMLFIND + ifdef PACKS + ifndef CREATE_LIB + ifdef THREADS + PACKS += threads + endif + endif + empty := + space := $(empty) $(empty) + comma := , + ifdef PREDS + PRE_OCAML_FIND_PREDICATES := $(subst $(space),$(comma),$(PREDS)) + PRE_OCAML_FIND_PACKAGES := $(subst $(space),$(comma),$(PACKS)) + OCAML_FIND_PREDICATES := -predicates $(PRE_OCAML_FIND_PREDICATES) + # OCAML_DEP_PREDICATES := -syntax $(PRE_OCAML_FIND_PREDICATES) + OCAML_FIND_PACKAGES := $(OCAML_FIND_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES) + OCAML_DEP_PACKAGES := $(OCAML_DEP_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES) + else + OCAML_FIND_PACKAGES := -package $(subst $(space),$(comma),$(PACKS)) + OCAML_DEP_PACKAGES := + endif + OCAML_FIND_LINKPKG := -linkpkg + REAL_OCAMLFIND := $(OCAMLFIND) + endif +endif + +export OCAML_FIND_PACKAGES +export OCAML_DEP_PACKAGES +export OCAML_FIND_LINKPKG +export REAL_OCAMLFIND + +ifndef OCAMLDOC + OCAMLDOC := ocamldoc +endif +export OCAMLDOC + +ifndef LATEX + LATEX := latex +endif +export LATEX + +ifndef DVIPS + DVIPS := dvips +endif +export DVIPS + +ifndef PS2PDF + PS2PDF := ps2pdf +endif +export PS2PDF + +ifndef OCAMLMAKEFILE + OCAMLMAKEFILE := OCamlMakefile +endif +export OCAMLMAKEFILE + +ifndef OCAMLLIBPATH + OCAMLLIBPATH := \ + $(shell $(OCAMLC) 2>/dev/null -where || echo /usr/lib/ocaml) +endif +export OCAMLLIBPATH + +ifndef OCAML_LIB_INSTALL + OCAML_LIB_INSTALL := $(OCAMLLIBPATH)/contrib +endif +export OCAML_LIB_INSTALL + +########################################################################### + +#################### change following sections only if +#################### you know what you are doing! + +# delete target files when a build command fails +.PHONY: .DELETE_ON_ERROR +.DELETE_ON_ERROR: + +# for pedants using "--warn-undefined-variables" +export MAYBE_IDL +export REAL_RESULT +export CAMLIDLFLAGS +export THREAD_FLAG +export RES_CLIB +export MAKEDLL +export ANNOT_FLAG +export C_OXRIDL +export SUBPROJS +export CFLAGS_WIN32 +export CPPFLAGS_WIN32 + +INCFLAGS := + +SHELL := /bin/sh + +MLDEPDIR := ._d +BCDIDIR := ._bcdi +NCDIDIR := ._ncdi + +FILTER_EXTNS := %.mli %.ml %.mll %.mly %.idl %.oxridl %.c %.$(EXT_CXX) %.rep %.zog %.glade + +FILTERED := $(filter $(FILTER_EXTNS), $(SOURCES)) +SOURCE_DIRS := $(filter-out ./, $(sort $(dir $(FILTERED)))) + +FILTERED_REP := $(filter %.rep, $(FILTERED)) +DEP_REP := $(FILTERED_REP:%.rep=$(MLDEPDIR)/%.d) +AUTO_REP := $(FILTERED_REP:.rep=.ml) + +FILTERED_ZOG := $(filter %.zog, $(FILTERED)) +DEP_ZOG := $(FILTERED_ZOG:%.zog=$(MLDEPDIR)/%.d) +AUTO_ZOG := $(FILTERED_ZOG:.zog=.ml) + +FILTERED_GLADE := $(filter %.glade, $(FILTERED)) +DEP_GLADE := $(FILTERED_GLADE:%.glade=$(MLDEPDIR)/%.d) +AUTO_GLADE := $(FILTERED_GLADE:.glade=.ml) + +FILTERED_ML := $(filter %.ml, $(FILTERED)) +DEP_ML := $(FILTERED_ML:%.ml=$(MLDEPDIR)/%.d) + +FILTERED_MLI := $(filter %.mli, $(FILTERED)) +DEP_MLI := $(FILTERED_MLI:.mli=.di) + +FILTERED_MLL := $(filter %.mll, $(FILTERED)) +DEP_MLL := $(FILTERED_MLL:%.mll=$(MLDEPDIR)/%.d) +AUTO_MLL := $(FILTERED_MLL:.mll=.ml) + +FILTERED_MLY := $(filter %.mly, $(FILTERED)) +DEP_MLY := $(FILTERED_MLY:%.mly=$(MLDEPDIR)/%.d) $(FILTERED_MLY:.mly=.di) +AUTO_MLY := $(FILTERED_MLY:.mly=.mli) $(FILTERED_MLY:.mly=.ml) + +FILTERED_IDL := $(filter %.idl, $(FILTERED)) +DEP_IDL := $(FILTERED_IDL:%.idl=$(MLDEPDIR)/%.d) $(FILTERED_IDL:.idl=.di) +C_IDL := $(FILTERED_IDL:%.idl=%_stubs.c) +ifndef NOIDLHEADER + C_IDL += $(FILTERED_IDL:.idl=.h) +endif +OBJ_C_IDL := $(FILTERED_IDL:%.idl=%_stubs.$(EXT_OBJ)) +AUTO_IDL := $(FILTERED_IDL:.idl=.mli) $(FILTERED_IDL:.idl=.ml) $(C_IDL) + +FILTERED_OXRIDL := $(filter %.oxridl, $(FILTERED)) +DEP_OXRIDL := $(FILTERED_OXRIDL:%.oxridl=$(MLDEPDIR)/%.d) $(FILTERED_OXRIDL:.oxridl=.di) +AUTO_OXRIDL := $(FILTERED_OXRIDL:.oxridl=.mli) $(FILTERED_OXRIDL:.oxridl=.ml) $(C_OXRIDL) + +FILTERED_C_CXX := $(filter %.c %.$(EXT_CXX), $(FILTERED)) +OBJ_C_CXX := $(FILTERED_C_CXX:.c=.$(EXT_OBJ)) +OBJ_C_CXX := $(OBJ_C_CXX:.$(EXT_CXX)=.$(EXT_OBJ)) + +PRE_TARGETS += $(AUTO_MLL) $(AUTO_MLY) $(AUTO_IDL) $(AUTO_OXRIDL) $(AUTO_ZOG) $(AUTO_REP) $(AUTO_GLADE) + +ALL_DEPS := $(DEP_ML) $(DEP_MLI) $(DEP_MLL) $(DEP_MLY) $(DEP_IDL) $(DEP_OXRIDL) $(DEP_ZOG) $(DEP_REP) $(DEP_GLADE) + +MLDEPS := $(filter %.d, $(ALL_DEPS)) +MLIDEPS := $(filter %.di, $(ALL_DEPS)) +BCDEPIS := $(MLIDEPS:%.di=$(BCDIDIR)/%.di) +NCDEPIS := $(MLIDEPS:%.di=$(NCDIDIR)/%.di) + +ALLML := $(filter %.mli %.ml %.mll %.mly %.idl %.oxridl %.rep %.zog %.glade, $(FILTERED)) + +IMPLO_INTF := $(ALLML:%.mli=%.mli.__) +IMPLO_INTF := $(foreach file, $(IMPLO_INTF), \ + $(basename $(file)).cmi $(basename $(file)).cmo) +IMPLO_INTF := $(filter-out %.mli.cmo, $(IMPLO_INTF)) +IMPLO_INTF := $(IMPLO_INTF:%.mli.cmi=%.cmi) + +IMPLX_INTF := $(IMPLO_INTF:.cmo=.cmx) + +INTF := $(filter %.cmi, $(IMPLO_INTF)) +IMPL_CMO := $(filter %.cmo, $(IMPLO_INTF)) +IMPL_CMX := $(IMPL_CMO:.cmo=.cmx) +IMPL_ASM := $(IMPL_CMO:.cmo=.asm) +IMPL_S := $(IMPL_CMO:.cmo=.s) + +OBJ_LINK := $(OBJ_C_IDL) $(OBJ_C_CXX) +OBJ_FILES := $(IMPL_CMO:.cmo=.$(EXT_OBJ)) $(OBJ_LINK) + +EXECS := $(addsuffix $(EXE), \ + $(sort $(TOPRESULT) $(BCRESULT) $(NCRESULT))) +ifdef WIN32 + EXECS += $(BCRESULT).dll $(NCRESULT).dll +endif + +CLIB_BASE := $(RESULT)$(RES_CLIB_SUF) +ifneq ($(strip $(OBJ_LINK)),) + RES_CLIB := lib$(CLIB_BASE).$(EXT_LIB) +endif + +ifdef WIN32 +DLLSONAME := $(CLIB_BASE).dll +else +DLLSONAME := dll$(CLIB_BASE).so +endif + +NONEXECS := $(INTF) $(IMPL_CMO) $(IMPL_CMX) $(IMPL_ASM) $(IMPL_S) \ + $(OBJ_FILES) $(PRE_TARGETS) $(BCRESULT).cma $(NCRESULT).cmxa \ + $(NCRESULT).$(EXT_LIB) $(BCRESULT).cmi $(BCRESULT).cmo \ + $(NCRESULT).cmi $(NCRESULT).cmx $(NCRESULT).o \ + $(RES_CLIB) $(IMPL_CMO:.cmo=.annot) \ + $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(LIB_PACK_NAME).cmx $(LIB_PACK_NAME).o + +ifndef STATIC + NONEXECS += $(DLLSONAME) +endif + +ifndef LIBINSTALL_FILES + LIBINSTALL_FILES := $(RESULT).mli $(RESULT).cmi $(RESULT).cma \ + $(RESULT).cmxa $(RESULT).$(EXT_LIB) $(RES_CLIB) + ifndef STATIC + ifneq ($(strip $(OBJ_LINK)),) + LIBINSTALL_FILES += $(DLLSONAME) + endif + endif +endif + +export LIBINSTALL_FILES + +ifdef WIN32 + # some extra stuff is created while linking DLLs + NONEXECS += $(BCRESULT).$(EXT_LIB) $(BCRESULT).exp $(NCRESULT).exp $(CLIB_BASE).exp $(CLIB_BASE).lib +endif + +TARGETS := $(EXECS) $(NONEXECS) + +# If there are IDL-files +ifneq ($(strip $(FILTERED_IDL)),) + MAYBE_IDL := -cclib -lcamlidl +endif + +ifdef USE_CAMLP4 + CAMLP4PATH := \ + $(shell $(CAMLP4) -where 2>/dev/null || echo /usr/lib/camlp4) + INCFLAGS := -I $(CAMLP4PATH) + CINCFLAGS := -I$(CAMLP4PATH) +endif + +DINCFLAGS := $(INCFLAGS) $(SOURCE_DIRS:%=-I %) $(OCAML_DEFAULT_DIRS:%=-I %) +INCFLAGS := $(DINCFLAGS) $(INCDIRS:%=-I %) +CINCFLAGS += $(SOURCE_DIRS:%=-I%) $(INCDIRS:%=-I%) $(OCAML_DEFAULT_DIRS:%=-I%) + +ifndef MSVC +CLIBFLAGS += $(SOURCE_DIRS:%=-L%) $(LIBDIRS:%=-L%) \ + $(EXTLIBDIRS:%=-L%) $(EXTLIBDIRS:%=-Wl,$(RPATH_FLAG)%) \ + $(OCAML_DEFAULT_DIRS:%=-L%) +endif + +ifndef PROFILING + INTF_OCAMLC := $(OCAMLC) +else + ifndef THREADS + INTF_OCAMLC := $(OCAMLCP) -p $(OCAMLCPFLAGS) + else + # OCaml does not support profiling byte code + # with threads (yet), therefore we force an error. + ifndef REAL_OCAMLC + $(error Profiling of multithreaded byte code not yet supported by OCaml) + endif + INTF_OCAMLC := $(OCAMLC) + endif +endif + +ifndef MSVC +COMMON_LDFLAGS := $(LDFLAGS:%=-ccopt %) $(SOURCE_DIRS:%=-ccopt -L%) \ + $(LIBDIRS:%=-ccopt -L%) $(EXTLIBDIRS:%=-ccopt -L%) \ + $(EXTLIBDIRS:%=-ccopt -Wl,$(RPATH_FLAG)%) \ + $(OCAML_DEFAULT_DIRS:%=-ccopt -L%) +else +COMMON_LDFLAGS := -ccopt "/link -NODEFAULTLIB:LIBC $(LDFLAGS:%=%) $(SOURCE_DIRS:%=-LIBPATH:%) \ + $(LIBDIRS:%=-LIBPATH:%) $(EXTLIBDIRS:%=-LIBPATH:%) \ + $(OCAML_DEFAULT_DIRS:%=-LIBPATH:%) " +endif + +CLIBS_OPTS := $(CLIBS:%=-cclib -l%) +ifdef MSVC + ifndef STATIC + # MSVC libraries do not have 'lib' prefix + CLIBS_OPTS := $(CLIBS:%=-cclib %.lib) + endif +endif + +ifneq ($(strip $(OBJ_LINK)),) + ifdef CREATE_LIB + OBJS_LIBS := -cclib -l$(CLIB_BASE) $(CLIBS_OPTS) $(MAYBE_IDL) + else + OBJS_LIBS := $(OBJ_LINK) $(CLIBS_OPTS) $(MAYBE_IDL) + endif +else + OBJS_LIBS := $(CLIBS_OPTS) $(MAYBE_IDL) +endif + +# If we have to make byte-code +ifndef REAL_OCAMLC + BYTE_OCAML := y + + # EXTRADEPS is added dependencies we have to insert for all + # executable files we generate. Ideally it should be all of the + # libraries we use, but it's hard to find the ones that get searched on + # the path since I don't know the paths built into the compiler, so + # just include the ones with slashes in their names. + EXTRADEPS := $(addsuffix .cma,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i)))) + SPECIAL_OCAMLFLAGS := $(OCAMLBCFLAGS) + + REAL_OCAMLC := $(INTF_OCAMLC) + + REAL_IMPL := $(IMPL_CMO) + REAL_IMPL_INTF := $(IMPLO_INTF) + IMPL_SUF := .cmo + + DEPFLAGS := + MAKE_DEPS := $(MLDEPS) $(BCDEPIS) + + ifdef CREATE_LIB + override CFLAGS := $(PIC_CFLAGS) $(CFLAGS) + override CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS) + ifndef STATIC + ifneq ($(strip $(OBJ_LINK)),) + MAKEDLL := $(DLLSONAME) + ALL_LDFLAGS := -dllib $(DLLSONAME) + endif + endif + endif + + ifndef NO_CUSTOM + ifneq "$(strip $(OBJ_LINK) $(THREADS) $(MAYBE_IDL) $(CLIBS))" "" + ALL_LDFLAGS += -custom + endif + endif + + ALL_LDFLAGS += $(INCFLAGS) $(OCAMLLDFLAGS) $(OCAMLBLDFLAGS) \ + $(COMMON_LDFLAGS) $(LIBS:%=%.cma) + CAMLIDLDLLFLAGS := + + ifdef THREADS + ifdef VMTHREADS + THREAD_FLAG := -vmthread + else + THREAD_FLAG := -thread + endif + ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS) + ifndef CREATE_LIB + ifndef REAL_OCAMLFIND + ALL_LDFLAGS := unix.cma threads.cma $(ALL_LDFLAGS) + endif + endif + endif + +# we have to make native-code +else + EXTRADEPS := $(addsuffix .cmxa,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i)))) + ifndef PROFILING + SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS) + PLDFLAGS := + else + SPECIAL_OCAMLFLAGS := -p $(OCAMLNCFLAGS) + PLDFLAGS := -p + endif + + REAL_IMPL := $(IMPL_CMX) + REAL_IMPL_INTF := $(IMPLX_INTF) + IMPL_SUF := .cmx + + override CPPFLAGS := -DNATIVE_CODE $(CPPFLAGS) + + DEPFLAGS := -native + MAKE_DEPS := $(MLDEPS) $(NCDEPIS) + + ALL_LDFLAGS := $(PLDFLAGS) $(INCFLAGS) $(OCAMLLDFLAGS) \ + $(OCAMLNLDFLAGS) $(COMMON_LDFLAGS) + CAMLIDLDLLFLAGS := -opt + + ifndef CREATE_LIB + ALL_LDFLAGS += $(LIBS:%=%.cmxa) + else + override CFLAGS := $(PIC_CFLAGS) $(CFLAGS) + override CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS) + endif + + ifdef THREADS + THREAD_FLAG := -thread + ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS) + ifndef CREATE_LIB + ifndef REAL_OCAMLFIND + ALL_LDFLAGS := unix.cmxa threads.cmxa $(ALL_LDFLAGS) + endif + endif + endif +endif + +export MAKE_DEPS + +ifdef ANNOTATE + ANNOT_FLAG := -dtypes +else +endif + +ALL_OCAMLCFLAGS := $(THREAD_FLAG) $(ANNOT_FLAG) $(OCAMLFLAGS) \ + $(INCFLAGS) $(SPECIAL_OCAMLFLAGS) + +ifdef make_deps + -include $(MAKE_DEPS) + PRE_TARGETS := +endif + +########################################################################### +# USER RULES + +# Call "OCamlMakefile QUIET=" to get rid of all of the @'s. +QUIET=@ + +# generates byte-code (default) +byte-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ + REAL_RESULT="$(BCRESULT)" make_deps=yes +bc: byte-code + +byte-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(BCRESULT)" make_deps=yes +bcnl: byte-code-nolink + +top: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(TOPRESULT) \ + REAL_RESULT="$(BCRESULT)" make_deps=yes + +# generates native-code + +native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + make_deps=yes +nc: native-code + +native-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + make_deps=yes +ncnl: native-code-nolink + +# generates byte-code libraries +byte-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).cma \ + REAL_RESULT="$(BCRESULT)" \ + CREATE_LIB=yes \ + make_deps=yes +bcl: byte-code-library + +# generates native-code libraries +native-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).cmxa \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + CREATE_LIB=yes \ + make_deps=yes +ncl: native-code-library + +ifdef WIN32 +# generates byte-code dll +byte-code-dll: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).dll \ + REAL_RESULT="$(BCRESULT)" \ + make_deps=yes +bcd: byte-code-dll + +# generates native-code dll +native-code-dll: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).dll \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + make_deps=yes +ncd: native-code-dll +endif + +# generates byte-code with debugging information +debug-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ + REAL_RESULT="$(BCRESULT)" make_deps=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dc: debug-code + +debug-code-nolink: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \ + REAL_RESULT="$(BCRESULT)" make_deps=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dcnl: debug-code-nolink + +# generates byte-code libraries with debugging information +debug-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).cma \ + REAL_RESULT="$(BCRESULT)" make_deps=yes \ + CREATE_LIB=yes \ + OCAMLFLAGS="-g $(OCAMLFLAGS)" \ + OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)" +dcl: debug-code-library + +# generates byte-code for profiling +profiling-byte-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \ + REAL_RESULT="$(BCRESULT)" PROFILING="y" \ + make_deps=yes +pbc: profiling-byte-code + +# generates native-code + +profiling-native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + PROFILING="y" \ + make_deps=yes +pnc: profiling-native-code + +# generates byte-code libraries +profiling-byte-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(BCRESULT).cma \ + REAL_RESULT="$(BCRESULT)" PROFILING="y" \ + CREATE_LIB=yes \ + make_deps=yes +pbcl: profiling-byte-code-library + +# generates native-code libraries +profiling-native-code-library: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(RES_CLIB) $(NCRESULT).cmxa \ + REAL_RESULT="$(NCRESULT)" PROFILING="y" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + CREATE_LIB=yes \ + make_deps=yes +pncl: profiling-native-code-library + +# packs byte-code objects +pack-byte-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT).cmo \ + REAL_RESULT="$(BCRESULT)" \ + PACK_LIB=yes make_deps=yes +pabc: pack-byte-code + +# packs native-code objects +pack-native-code: $(PRE_TARGETS) + $(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \ + $(NCRESULT).cmx $(NCRESULT).o \ + REAL_RESULT="$(NCRESULT)" \ + REAL_OCAMLC="$(OCAMLOPT)" \ + PACK_LIB=yes make_deps=yes +panc: pack-native-code + +# generates HTML-documentation +htdoc: doc/$(RESULT)/html + +# generates Latex-documentation +ladoc: doc/$(RESULT)/latex + +# generates PostScript-documentation +psdoc: doc/$(RESULT)/latex/doc.ps + +# generates PDF-documentation +pdfdoc: doc/$(RESULT)/latex/doc.pdf + +# generates all supported forms of documentation +doc: htdoc ladoc psdoc pdfdoc + +########################################################################### +# LOW LEVEL RULES + +$(REAL_RESULT): $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) \ + $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \ + $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ + $(REAL_IMPL) + +nolink: $(REAL_IMPL_INTF) $(OBJ_LINK) + +ifdef WIN32 +$(REAL_RESULT).dll: $(REAL_IMPL_INTF) $(OBJ_LINK) + $(CAMLIDLDLL) $(CAMLIDLDLLFLAGS) $(OBJ_LINK) $(CLIBS) \ + -o $@ $(REAL_IMPL) +endif + +%$(TOPSUFFIX): $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) + $(REAL_OCAMLFIND) $(OCAMLMKTOP) \ + $(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \ + $(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \ + $(REAL_IMPL) + +.SUFFIXES: .mli .ml .cmi .cmo .cmx .cma .cmxa .$(EXT_OBJ) \ + .mly .di .d .$(EXT_LIB) .idl %.oxridl .c .$(EXT_CXX) .h .so \ + .rep .zog .glade + +ifndef STATIC +ifdef MINGW +$(DLLSONAME): $(OBJ_LINK) + $(CC) $(CFLAGS) $(CFLAGS_WIN32) $(OBJ_LINK) -shared -o $@ \ + -Wl,--whole-archive $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/lib%.a))) \ + $(OCAMLLIBPATH)/ocamlrun.a \ + -Wl,--export-all-symbols \ + -Wl,--no-whole-archive +else +ifdef MSVC +$(DLLSONAME): $(OBJ_LINK) + link /NOLOGO /DLL /OUT:$@ $(OBJ_LINK) \ + $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/%.lib))) \ + $(OCAMLLIBPATH)/ocamlrun.lib + +else +$(DLLSONAME): $(OBJ_LINK) + $(OCAMLMKLIB) $(INCFLAGS) $(CLIBFLAGS) \ + -o $(CLIB_BASE) $(OBJ_LINK) $(CLIBS:%=-l%) \ + $(OCAMLMKLIB_FLAGS) +endif +endif +endif + +ifndef LIB_PACK_NAME +$(RESULT).cma: $(REAL_IMPL_INTF) $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \ + $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(REAL_IMPL) + +$(RESULT).cmxa $(RESULT).$(EXT_LIB): $(REAL_IMPL_INTF) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \ + $(OCAMLNLDFLAGS) -o $@ $(REAL_IMPL) +else +ifdef BYTE_OCAML +$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo: $(REAL_IMPL_INTF) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmo $(REAL_IMPL) +else +$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx: $(REAL_IMPL_INTF) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmx $(REAL_IMPL) +endif + +$(RESULT).cma: $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \ + $(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(LIB_PACK_NAME).cmo + +$(RESULT).cmxa $(RESULT).$(EXT_LIB): $(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx $(EXTRADEPS) $(RESULTDEPS) + $(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \ + $(OCAMLNLDFLAGS) -o $@ $(LIB_PACK_NAME).cmx +endif + +$(RES_CLIB): $(OBJ_LINK) +ifndef MSVC + ifneq ($(strip $(OBJ_LINK)),) + $(AR) rcs $@ $(OBJ_LINK) + endif +else + ifneq ($(strip $(OBJ_LINK)),) + lib -nologo -debugtype:cv -out:$(RES_CLIB) $(OBJ_LINK) + endif +endif + +.mli.cmi: $(EXTRADEPS) + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + else \ + echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp \"$$pp $(PPFLAGS)\" $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp "$$pp $(PPFLAGS)" $(THREAD_FLAG) $(ANNOT_FLAG) \ + $(OCAMLFLAGS) $(INCFLAGS) $<; \ + fi + +.ml.cmi .ml.$(EXT_OBJ) .ml.cmx .ml.cmo: $(EXTRADEPS) + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(ALL_OCAMLCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c $(ALL_OCAMLCFLAGS) $<; \ + else \ + echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp \"$$pp $(PPFLAGS)\" $(ALL_OCAMLCFLAGS) $<; \ + $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \ + -c -pp "$$pp $(PPFLAGS)" $(ALL_OCAMLCFLAGS) $<; \ + fi + +ifdef PACK_LIB +$(REAL_RESULT).cmo $(REAL_RESULT).cmx $(REAL_RESULT).o: $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) + $(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack $(ALL_LDFLAGS) \ + $(OBJS_LIBS) -o $@ $(REAL_IMPL) +endif + +.PRECIOUS: %.ml +%.ml: %.mll + $(OCAMLLEX) $< + +.PRECIOUS: %.ml %.mli +%.ml %.mli: %.mly + $(OCAMLYACC) $(YFLAGS) $< + $(QUIET)pp=`sed -n -e 's/.*(\*pp \([^*]*\) \*).*/\1/p;q' $<`; \ + if [ ! -z "$$pp" ]; then \ + mv $*.ml $*.ml.temporary; \ + echo "(*pp $$pp $(PPFLAGS)*)" > $*.ml; \ + cat $*.ml.temporary >> $*.ml; \ + rm $*.ml.temporary; \ + mv $*.mli $*.mli.temporary; \ + echo "(*pp $$pp $(PPFLAGS)*)" > $*.mli; \ + cat $*.mli.temporary >> $*.mli; \ + rm $*.mli.temporary; \ + fi + + +.PRECIOUS: %.ml +%.ml: %.rep + $(CAMELEON_REPORT) $(CAMELEON_REPORT_FLAGS) -gen $< + +.PRECIOUS: %.ml +%.ml: %.zog + $(CAMELEON_ZOGGY) $(CAMELEON_ZOGGY_FLAGS) -impl $< > $@ + +.PRECIOUS: %.ml +%.ml: %.glade + $(OCAML_GLADECC) $(OCAML_GLADECC_FLAGS) $< > $@ + +.PRECIOUS: %.ml %.mli +%.ml %.mli: %.oxridl + $(OXRIDL) $< + +.PRECIOUS: %.ml %.mli %_stubs.c %.h +%.ml %.mli %_stubs.c %.h: %.idl + $(CAMLIDL) $(MAYBE_IDL_HEADER) $(IDLFLAGS) \ + $(CAMLIDLFLAGS) $< + $(QUIET)if [ $(NOIDLHEADER) ]; then touch $*.h; fi + +.c.$(EXT_OBJ): + $(OCAMLC) -c -cc "$(CC)" -ccopt "$(CFLAGS) \ + $(CPPFLAGS) $(CPPFLAGS_WIN32) \ + $(CFLAGS_WIN32) $(CINCFLAGS) $(CFLAG_O)$@ " $< + +.$(EXT_CXX).$(EXT_OBJ): + $(CXX) -c $(CXXFLAGS) $(CINCFLAGS) $(CPPFLAGS) \ + -I'$(OCAMLLIBPATH)' \ + $< $(CFLAG_O)$@ + +$(MLDEPDIR)/%.d: %.ml + $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + $(DINCFLAGS) $< > $@; \ + else \ + echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + -pp \"$$pp $(PPFLAGS)\" $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \ + -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \ + fi + +$(BCDIDIR)/%.di $(NCDIDIR)/%.di: %.mli + $(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< > $@; \ + else \ + echo $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \ + -pp \"$$pp $(PPFLAGS)\" $(DINCFLAGS) $< \> $@; \ + $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \ + -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \ + fi + +doc/$(RESULT)/html: $(DOC_FILES) + #rm -rf $@ + #mkdir -p $@ + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + echo $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \ + $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \ + else \ + echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -html -d $@ $(OCAMLDOCFLAGS) \ + $(INCFLAGS) $(DOC_FILES); \ + $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -html -d $@ $(OCAMLDOCFLAGS) \ + $(INCFLAGS) $(DOC_FILES); \ + fi + +doc/$(RESULT)/latex: $(DOC_FILES) + #rm -rf $@ + #mkdir -p $@ + $(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \ + if [ -z "$$pp" ]; then \ + echo $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) \ + $(DOC_FILES) -o $@/doc.tex; \ + $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES) \ + -o $@/doc.tex; \ + else \ + echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -latex $(OCAMLDOCFLAGS) \ + $(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \ + $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -latex $(OCAMLDOCFLAGS) \ + $(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \ + fi + +doc/$(RESULT)/latex/doc.ps: doc/$(RESULT)/latex + cd doc/$(RESULT)/latex && \ + $(LATEX) doc.tex && \ + $(LATEX) doc.tex && \ + $(DVIPS) $(DVIPSFLAGS) doc.dvi -o $(@F) + +doc/$(RESULT)/latex/doc.pdf: doc/$(RESULT)/latex/doc.ps + cd doc/$(RESULT)/latex && $(PS2PDF) $(<F) + +define make_subproj +.PHONY: +subproj_$(1): + $$(eval $$(call PROJ_$(1))) + $(QUIET)if [ "$(SUBTARGET)" != "all" ]; then \ + $(MAKE) -f $(OCAMLMAKEFILE) $(SUBTARGET); \ + fi +endef + +$(foreach subproj,$(SUBPROJS),$(eval $(call make_subproj,$(subproj)))) + +.PHONY: +subprojs: $(SUBPROJS:%=subproj_%) + +########################################################################### +# (UN)INSTALL RULES FOR LIBRARIES + +.PHONY: libinstall +libinstall: all + $(QUIET)printf "\nInstalling library with ocamlfind\n" + $(OCAMLFIND) install $(OCAMLFIND_INSTFLAGS) $(RESULT) META $(LIBINSTALL_FILES) + $(QUIET)printf "\nInstallation successful.\n" + +.PHONY: libuninstall +libuninstall: + $(QUIET)printf "\nUninstalling library with ocamlfind\n" + $(OCAMLFIND) remove $(OCAMLFIND_INSTFLAGS) $(RESULT) + $(QUIET)printf "\nUninstallation successful.\n" + +.PHONY: rawinstall +rawinstall: all + $(QUIET)printf "\nInstalling library to: $(OCAML_LIB_INSTALL)\n" + -install -d $(OCAML_LIB_INSTALL) + for i in $(LIBINSTALL_FILES); do \ + if [ -f $$i ]; then \ + install -c -m 0644 $$i $(OCAML_LIB_INSTALL); \ + fi; \ + done + $(QUIET)printf "\nInstallation successful.\n" + +.PHONY: rawuninstall +rawuninstall: + $(QUIET)printf "\nUninstalling library from: $(OCAML_LIB_INSTALL)\n" + cd $(OCAML_LIB_INSTALL) && rm $(notdir $(LIBINSTALL_FILES)) + $(QUIET)printf "\nUninstallation successful.\n" + +########################################################################### +# MAINTAINANCE RULES + +.PHONY: clean +clean:: + rm -f $(TARGETS) $(TRASH) + rm -rf $(BCDIDIR) $(NCDIDIR) $(MLDEPDIR) + +.PHONY: cleanup +cleanup:: + rm -f $(NONEXECS) $(TRASH) + rm -rf $(BCDIDIR) $(NCDIDIR) $(MLDEPDIR) + +.PHONY: clean-doc +clean-doc:: + rm -rf doc + +.PHONY: nobackup +nobackup: + rm -f *.bak *~ *.dup diff --git a/examples/ubigraph/Ubigraph.ml b/examples/ubigraph/Ubigraph.ml new file mode 100644 index 0000000..7998eae --- /dev/null +++ b/examples/ubigraph/Ubigraph.ml @@ -0,0 +1,169 @@ +(* + * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet + * Copyright (C) 2008 Dave Benjamin (dave@ramenlabs.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + *) + +(* Automatically generated from an XML-RPC server + by running the following command: + + ../genclient/genclient -i http://localhost:20738/RPC2 +*) + +exception Type_error of string + +class client url = + let rpc = new XmlRpc.client url in +object (self) + method rpc = rpc + + method system = object + method shutdown _0 = + let result = rpc#call "system.shutdown" [`String _0] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method multicall _0 = + let result = rpc#call "system.multicall" [`Array _0] in + match result with + | `Array r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method methodHelp _0 = + let result = rpc#call "system.methodHelp" [`String _0] in + match result with + | `String r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method methodSignature _0 = + let result = rpc#call "system.methodSignature" [`String _0] in + match result with + | `Array r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method listMethods () = + let result = rpc#call "system.listMethods" [] in + match result with + | `Array r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + end + + method ubigraph = object + method change_edge_style _0 _1 = + let result = rpc#call "ubigraph.change_edge_style" [`Int32 _0; `Int32 _1] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_edge_style_w_id _0 _1 = + let result = rpc#call "ubigraph.new_edge_style_w_id" [`Int32 _0; `Int32 _1] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_edge_style _0 = + let result = rpc#call "ubigraph.new_edge_style" [`Int32 _0] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method set_edge_style_attribute _0 _1 _2 = + let result = rpc#call "ubigraph.set_edge_style_attribute" [`Int32 _0; `String _1; `String _2] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method set_edge_attribute _0 _1 _2 = + let result = rpc#call "ubigraph.set_edge_attribute" [`Int32 _0; `String _1; `String _2] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method change_vertex_style _0 _1 = + let result = rpc#call "ubigraph.change_vertex_style" [`Int32 _0; `Int32 _1] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_vertex_style_w_id _0 _1 = + let result = rpc#call "ubigraph.new_vertex_style_w_id" [`Int32 _0; `Int32 _1] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_vertex_style _0 = + let result = rpc#call "ubigraph.new_vertex_style" [`Int32 _0] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method set_vertex_style_attribute _0 _1 _2 = + let result = rpc#call "ubigraph.set_vertex_style_attribute" [`Int32 _0; `String _1; `String _2] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method set_vertex_attribute _0 _1 _2 = + let result = rpc#call "ubigraph.set_vertex_attribute" [`Int32 _0; `String _1; `String _2] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method clear () = + let result = rpc#call "ubigraph.clear" [] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method remove_edge _0 = + let result = rpc#call "ubigraph.remove_edge" [`Int32 _0] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method remove_vertex _0 = + let result = rpc#call "ubigraph.remove_vertex" [`Int32 _0] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_edge _0 _1 = + let result = rpc#call "ubigraph.new_edge" [`Int32 _0; `Int32 _1] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_edge_w_id _0 _1 _2 = + let result = rpc#call "ubigraph.new_edge_w_id" [`Int32 _0; `Int32 _1; `Int32 _2] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_vertex () = + let result = rpc#call "ubigraph.new_vertex" [] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + + method new_vertex_w_id _0 = + let result = rpc#call "ubigraph.new_vertex_w_id" [`Int32 _0] in + match result with + | `Int r -> Int32.of_int r | `Int32 r -> r + | other -> raise (Type_error (XmlRpc.dump other)) + end + +end diff --git a/examples/ubigraph/Ubigraph.mli b/examples/ubigraph/Ubigraph.mli new file mode 100644 index 0000000..363354a --- /dev/null +++ b/examples/ubigraph/Ubigraph.mli @@ -0,0 +1,51 @@ +(* + * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet + * Copyright (C) 2008 Dave Benjamin (dave@ramenlabs.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + *) + +exception Type_error of string + +class client : string -> +object + method rpc : XmlRpc.client + + method ubigraph : + < change_edge_style : int32 -> int32 -> int32; + change_vertex_style : int32 -> int32 -> int32; + clear : unit -> int32; + new_edge : int32 -> int32 -> int32; + new_edge_style : int32 -> int32; + new_edge_style_w_id : int32 -> int32 -> int32; + new_edge_w_id : int32 -> int32 -> int32 -> int32; + new_vertex : unit -> int32; + new_vertex_style : int32 -> int32; + new_vertex_style_w_id : int32 -> int32 -> int32; + new_vertex_w_id : int32 -> int32; + remove_edge : int32 -> int32; + remove_vertex : int32 -> int32; + set_edge_attribute : int32 -> string -> string -> int32; + set_edge_style_attribute : int32 -> string -> string -> int32; + set_vertex_attribute : int32 -> string -> string -> int32; + set_vertex_style_attribute : int32 -> string -> string -> int32 > + + method system : + < listMethods : unit -> XmlRpc.value list; + methodHelp : string -> string; + methodSignature : string -> XmlRpc.value list; + multicall : XmlRpc.value list -> XmlRpc.value list; + shutdown : string -> int32 > +end diff --git a/examples/ubigraph/test.ml b/examples/ubigraph/test.ml new file mode 100644 index 0000000..892c564 --- /dev/null +++ b/examples/ubigraph/test.ml @@ -0,0 +1,54 @@ +(* + * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet + * Copyright (C) 2008 Dave Benjamin (dave@ramenlabs.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + *) + +(* Based on Python example, "examples/Python/ubigraph_example.py", + distributed with Ubigraph. For details, see the Ubigraph website: + http://ubietylab.net/ubigraph/ +*) + +let client = new Ubigraph.client "http://localhost:20738/RPC2" +let u = client#ubigraph +let _ = u#clear () + +let x = u#new_vertex () +let _ = u#set_vertex_attribute x "shape" "sphere" +let _ = u#set_vertex_attribute x "color" "#ffff00" + +let small_red = u#new_vertex_style 0l +let _ = u#set_vertex_style_attribute small_red "shape" "sphere" +let _ = u#set_vertex_style_attribute small_red "color" "#ff0000" +let _ = u#set_vertex_style_attribute small_red "size" "0.2" + +let previous_r = ref None +let () = + for i = 0 to 9 do + let r = u#new_vertex () in + let _ = u#change_vertex_style r small_red in + let _ = u#set_vertex_attribute r "label" (string_of_int i) in + let e = u#new_edge x r in + let _ = u#set_edge_attribute e "arrow" "true" in + match !previous_r with + | None -> + previous_r := Some r + | Some r' -> + let e = u#new_edge r r' in + let _ = u#set_edge_attribute e "spline" "true" in + let _ = u#set_edge_attribute e "stroke" "dashed" in + previous_r := Some r + done diff --git a/examples/wordpress/WordPress.ml b/examples/wordpress/WordPress.ml index d797545..f816848 100644 --- a/examples/wordpress/WordPress.ml +++ b/examples/wordpress/WordPress.ml @@ -1,6 +1,6 @@ (* * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet - * Copyright (C) 2007 Dave Benjamin (dave@ramenlabs.com) + * Copyright (C) 2007-2009 Dave Benjamin (dave@ramenlabs.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,6 +20,13 @@ exception Type_error of string exception Unknown_field of string +let strict = ref false + +let warn exn = + if !strict + then raise exn + else prerr_endline (Printexc.to_string exn) + let map_array f = function | `Array items -> List.map f items | other -> raise (Type_error (XmlRpc.dump other)) @@ -33,6 +40,35 @@ let int_value = function | `String s -> int_of_string s | other -> raise (Type_error (XmlRpc.dump other)) +module Blog = struct + type t = { mutable is_admin : bool; + mutable url : string; + mutable blog_id : int; + mutable blog_name : string; + mutable xmlrpc : string; } + + let make () = + {is_admin=false; + url=""; + blog_id=0; + blog_name=""; + xmlrpc=""} + + let of_xmlrpc value = + let result = make () in + iter_struct + (function + | ("isAdmin", `Boolean v) -> result.is_admin <- v + | ("url", `String v) -> result.url <- v + | ("blogid", `String v) -> result.blog_id <- int_of_string v + | ("blogid", `Int v) -> result.blog_id <- v + | ("blogName", `String v) -> result.blog_name <- v + | ("xmlrpc", `String v) -> result.xmlrpc <- v + | (field, _) -> warn (Unknown_field field)) + value; + result +end + module Category = struct type t = { mutable category_id : int; mutable parent_id : int; @@ -54,12 +90,172 @@ module Category = struct iter_struct (function | ("categoryId", `String v) -> result.category_id <- int_of_string v + | ("categoryId", `Int v) -> result.category_id <- v | ("parentId", `String v) -> result.parent_id <- int_of_string v + | ("parentId", `Int v) -> result.parent_id <- v | ("description", `String v) -> result.description <- v | ("categoryName", `String v) -> result.category_name <- v | ("htmlUrl", `String v) -> result.html_url <- v | ("rssUrl", `String v) -> result.rss_url <- v - | (field, _) -> raise (Unknown_field field)) + | (field, _) -> warn (Unknown_field field)) + value; + result +end + +module CommentCount = struct + type t = { mutable approved : int; + mutable awaiting_moderation : int; + mutable spam : int; + mutable total_comments : int; } + + let make () = + {approved=0; + awaiting_moderation=0; + spam=0; + total_comments=0} + + let of_xmlrpc value = + let result = make () in + iter_struct + (function + | ("approved", `String v) -> result.approved <- int_of_string v + | ("approved", `Int v) -> result.approved <- v + | ("awaiting_moderation", `Int v) -> result.awaiting_moderation <- v + | ("spam", `Int v) -> result.spam <- v + | ("total_comments", `Int v) -> result.total_comments <- v + | (field, _) -> warn (Unknown_field field)) + value; + result +end + +module Comment = struct + type t = { mutable date_created : XmlRpcDateTime.t; + mutable user_id : int; + mutable comment_id : int; + mutable parent : int; + mutable status : string; + mutable content : string; + mutable link : string; + mutable post_id : int; + mutable post_title : string; + mutable author : string; + mutable author_url : string; + mutable author_email : string; + mutable author_ip : string; + mutable typ : string } + + let make () = + {date_created=(0,0,0,0,0,0,0); + user_id=0; + comment_id=0; + parent=0; + status=""; + content=""; + link=""; + post_id=0; + post_title=""; + author=""; + author_url=""; + author_email=""; + author_ip=""; + typ=""} + + let of_xmlrpc value = + let result = make () in + iter_struct + (function + | ("date_created_gmt", `DateTime v) -> result.date_created <- v + | ("user_id", `String v) -> result.user_id <- int_of_string v + | ("user_id", `Int v) -> result.user_id <- v + | ("comment_id", `String v) -> result.comment_id <- int_of_string v + | ("comment_id", `Int v) -> result.comment_id <- v + | ("parent", `String v) -> result.parent <- int_of_string v + | ("parent", `Int v) -> result.parent <- v + | ("status", `String v) -> result.status <- v + | ("content", `String v) -> result.content <- v + | ("link", `String v) -> result.link <- v + | ("post_id", `String v) -> result.post_id <- int_of_string v + | ("post_id", `Int v) -> result.post_id <- v + | ("post_title", `String v) -> result.post_title <- v + | ("author", `String v) -> result.author <- v + | ("author_url", `String v) -> result.author_url <- v + | ("author_email", `String v) -> result.author_email <- v + | ("author_ip", `String v) -> result.author_ip <- v + | ("type", `String v) -> result.typ <- v + | (field, _) -> warn (Unknown_field field)) + value; + result + + let to_xmlrpc comment = + `Struct ["date_created_gmt", `DateTime (XmlRpcDateTime.set_tz_offset 0 + comment.date_created); + "user_id", `Int comment.user_id; + "comment_id", `Int comment.comment_id; + "parent", `Int comment.parent; + "status", `String comment.status; + "content", `String comment.content; + "link", `String comment.link; + "post_id", `Int comment.post_id; + "post_title", `String comment.post_title; + "author", `String comment.author; + "author_url", `String comment.author_url; + "author_email", `String comment.author_email; + "author_ip", `String comment.author_ip; + "type", `String comment.typ] +end + +module CustomField = struct + type t = { mutable id : int option; + mutable key : string option; + mutable value : string } + + let make () = + {id=None; + key=None; + value=""} + + let of_xmlrpc value = + let result = make () in + iter_struct + (function + | ("id", `String v) -> result.id <- Some (int_of_string v) + | ("id", `Int v) -> result.id <- Some v + | ("key", `String v) -> result.key <- Some v + | ("value", `String v) -> result.value <- v + | (field, _) -> warn (Unknown_field field)) + value; + result + + let to_xmlrpc field = + match field with + | {id=None; key=None; value=value} -> + `Struct ["value", `String value] + | {id=Some id; key=None; value=value} -> + `Struct ["id", `Int id; "value", `String value] + | {id=None; key=Some key; value=value} -> + `Struct ["key", `String key; "value", `String value] + | {id=Some id; key=Some key; value=value} -> + `Struct ["id", `Int id; "key", `String key; "value", `String value] +end + +module Option = struct + type t = { mutable desc : string; + mutable readonly : bool; + mutable value : string; } + + let make () = + {desc=""; + readonly=false; + value=""} + + let of_xmlrpc value = + let result = make () in + iter_struct + (function + | ("desc", `String v) -> result.desc <- v + | ("readonly", `Boolean v) -> result.readonly <- v + | ("value", `String v) -> result.value <- v + | (field, _) -> warn (Unknown_field field)) value; result end @@ -83,11 +279,12 @@ module User = struct iter_struct (function | ("user_id", `String v) -> result.user_id <- int_of_string v + | ("user_id", `Int v) -> result.user_id <- v | ("user_login", `String v) -> result.user_login <- v | ("display_name", `String v) -> result.display_name <- v | ("user_email", `String v) -> result.user_email <- v | ("meta_value", `String v) -> result.meta_value <- v - | (field, _) -> raise (Unknown_field field)) + | (field, _) -> warn (Unknown_field field)) value; result end @@ -110,11 +307,13 @@ module PageListItem = struct iter_struct (function | ("page_id", `String v) -> result.page_id <- int_of_string v + | ("page_id", `Int v) -> result.page_id <- v | ("page_title", `String v) -> result.page_title <- v | ("page_parent_id", `String v) -> result.page_parent_id <- int_of_string v + | ("page_parent_id", `Int v) -> result.page_parent_id <- v | ("dateCreated", `DateTime v) -> result.date_created <- v | ("date_created_gmt", `DateTime v) -> result.date_created <- v - | (field, _) -> raise (Unknown_field field)) + | (field, _) -> warn (Unknown_field field)) value; result end @@ -140,7 +339,9 @@ module Page = struct mutable wp_page_parent_title : string; mutable wp_page_order : int; mutable wp_author_id : int; - mutable wp_author_display_name : string; } + mutable wp_author_display_name : string; + mutable custom_fields : CustomField.t list; + mutable wp_page_template : string; } let make () = {date_created=(0,0,0,0,0,0,0); @@ -163,7 +364,9 @@ module Page = struct wp_page_parent_title=""; wp_page_order=0; wp_author_id=0; - wp_author_display_name=""} + wp_author_display_name=""; + custom_fields=[]; + wp_page_template=""} let of_xmlrpc value = let result = make () in @@ -172,7 +375,9 @@ module Page = struct | ("dateCreated", `DateTime v) -> result.date_created <- v | ("date_created_gmt", `DateTime v) -> result.date_created <- v | ("userid", `String v) -> result.user_id <- int_of_string v + | ("userid", `Int v) -> result.user_id <- v | ("page_id", `String v) -> result.page_id <- int_of_string v + | ("page_id", `Int v) -> result.page_id <- v | ("page_status", `String v) -> result.page_status <- v | ("description", `String v) -> result.description <- v | ("title", `String v) -> result.title <- v @@ -182,48 +387,75 @@ module Page = struct result.categories <- List.map XmlRpc.dump v | ("excerpt", `String v) -> result.excerpt <- v | ("text_more", `String v) -> result.text_more <- v + | ("mt_excerpt", `String v) -> result.excerpt <- v + | ("mt_text_more", `String v) -> result.text_more <- v | ("mt_allow_comments", `Int v) -> result.mt_allow_comments <- v<>0 + | ("mt_allow_comments", `Boolean v) -> result.mt_allow_comments <- v | ("mt_allow_pings", `Int v) -> result.mt_allow_pings <- v<>0 + | ("mt_allow_pings", `Boolean v) -> result.mt_allow_pings <- v | ("wp_slug", `String v) -> result.wp_slug <- v | ("wp_password", `String v) -> result.wp_password <- v | ("wp_author", `String v) -> result.wp_author <- v - | ("wp_page_parent_id", `Int v) -> - result.wp_page_parent_id <- v + | ("wp_author_display_name", `String v) -> + result.wp_author_display_name <- v | ("wp_page_parent_id", `String v) -> result.wp_page_parent_id <- int_of_string v + | ("wp_page_parent_id", `Int v) -> + result.wp_page_parent_id <- v | ("wp_page_parent_title", `String v) -> result.wp_page_parent_title <- v + | ("wp_page_order", `String v) -> + result.wp_page_order <- int_of_string v | ("wp_page_order", `Int v) -> result.wp_page_order <- v | ("wp_author_id", `String v) -> result.wp_author_id <- int_of_string v - | ("wp_author_display_name", `String v) -> - result.wp_author_display_name <- v - | (field, _) -> raise (Unknown_field field)) + | ("wp_author_id", `Int v) -> + result.wp_author_id <- v + | ("custom_fields", `Array v) -> + result.custom_fields <- List.map CustomField.of_xmlrpc v + | ("wp_page_template", `String v) -> + result.wp_page_template <- v + | (field, _) -> warn (Unknown_field field)) value; result let to_xmlrpc page = - `Struct ["wp_slug", `String page.wp_slug; + `Struct ["userid", `Int page.user_id; + "page_id", `Int page.page_id; + "page_status", `String page.page_status; + "wp_slug", `String page.wp_slug; "wp_password", `String page.wp_password; + "wp_author", `String page.wp_author; + "wp_author_display_name", `String page.wp_author_display_name; "wp_page_parent_id", `Int page.wp_page_parent_id; + "wp_page_parent_title", `String page.wp_page_parent_title; "wp_page_order", `Int page.wp_page_order; "wp_author_id", `Int page.wp_author_id; "title", `String page.title; "description", `String page.description; + "link", `String page.link; + "permaLink", `String page.permalink; "mt_excerpt", `String page.excerpt; "mt_text_more", `String page.text_more; "mt_allow_comments", `Boolean page.mt_allow_comments; "mt_allow_pings", `Boolean page.mt_allow_pings; "dateCreated", `DateTime page.date_created; + "date_created_gmt", `DateTime (XmlRpcDateTime.set_tz_offset 0 + page.date_created); "categories", `Array (List.map (fun s -> `String s) - page.categories)] + page.categories); + "custom_fields", `Array (List.map + CustomField.to_xmlrpc + page.custom_fields); + "wp_page_template", `String page.wp_page_template] end module Post = struct type t = { mutable user_id : int; mutable post_id : int; + mutable post_status : string; mutable date_created : XmlRpcDateTime.t; mutable description : string; mutable title : string; @@ -238,12 +470,14 @@ module Post = struct mutable wp_slug : string; mutable wp_password : string; mutable wp_author_id : int; - mutable wp_author_display_name : string; } + mutable wp_author_display_name : string; + mutable custom_fields : CustomField.t list; } let make () = {date_created=(0,0,0,0,0,0,0); user_id=0; post_id=0; + post_status=""; description=""; title=""; link=""; @@ -257,7 +491,8 @@ module Post = struct wp_slug=""; wp_password=""; wp_author_id=0; - wp_author_display_name=""} + wp_author_display_name=""; + custom_fields=[]} let of_xmlrpc value = let result = make () in @@ -266,7 +501,10 @@ module Post = struct | ("dateCreated", `DateTime v) -> result.date_created <- v | ("date_created_gmt", `DateTime v) -> result.date_created <- v | ("userid", `String v) -> result.user_id <- int_of_string v + | ("userid", `Int v) -> result.user_id <- v | ("postid", `String v) -> result.post_id <- int_of_string v + | ("postid", `Int v) -> result.post_id <- v + | ("post_status", `String v) -> result.post_status <- v | ("description", `String v) -> result.description <- v | ("title", `String v) -> result.title <- v | ("link", `String v) -> result.link <- v @@ -276,20 +514,33 @@ module Post = struct | ("mt_excerpt", `String v) -> result.excerpt <- v | ("mt_text_more", `String v) -> result.text_more <- v | ("mt_allow_comments", `Int v) -> result.mt_allow_comments <- v<>0 + | ("mt_allow_comments", `Boolean v) -> result.mt_allow_comments <- v | ("mt_allow_pings", `Int v) -> result.mt_allow_pings <- v<>0 + | ("mt_allow_pings", `Boolean v) -> result.mt_allow_pings <- v | ("mt_keywords", `String v) -> result.mt_keywords <- v | ("wp_slug", `String v) -> result.wp_slug <- v | ("wp_password", `String v) -> result.wp_password <- v | ("wp_author_id", `String v) -> result.wp_author_id <- int_of_string v - | ("wp_author_display_name", `String v) -> result.wp_author_display_name <- v - | (field, _) -> raise (Unknown_field field)) + | ("wp_author_id", `Int v) -> result.wp_author_id <- v + | ("wp_author_display_name", `String v) -> + result.wp_author_display_name <- v + | ("custom_fields", `Array v) -> + result.custom_fields <- List.map CustomField.of_xmlrpc v + | (field, _) -> warn (Unknown_field field)) value; result let to_xmlrpc post = `Struct ["dateCreated", `DateTime post.date_created; + "date_created_gmt", `DateTime (XmlRpcDateTime.set_tz_offset 0 + post.date_created); + "userid", `Int post.user_id; + "postid", `Int post.post_id; + "post_status", `String post.post_status; "description", `String post.description; "title", `String post.title; + "link", `String post.link; + "permaLink", `String post.permalink; "categories", `Array (List.map (fun s -> `String s) post.categories); @@ -300,7 +551,11 @@ module Post = struct "mt_keywords", `String post.mt_keywords; "wp_slug", `String post.wp_slug; "wp_password", `String post.wp_password; - "wp_author_id", `Int post.wp_author_id] + "wp_author_id", `Int post.wp_author_id; + "wp_author_display_name", `String post.wp_author_display_name; + "custom_fields", `Array (List.map + CustomField.to_xmlrpc + post.custom_fields)]; end class api ~url ~blog_id ~username ~password = @@ -326,6 +581,16 @@ object (self) method get_page_list () = map_array PageListItem.of_xmlrpc (rpc#call "wp.getPageList" std_args) + method get_page_status_list () = + match rpc#call "wp.getPageStatusList" std_args with + | `Struct pairs -> List.map (fun (k, v) -> (k, XmlRpc.dump v)) pairs + | other -> raise (Type_error (XmlRpc.dump other)) + + method get_page_templates () = + match rpc#call "wp.getPageTemplates" std_args with + | `Struct pairs -> List.map (fun (k, v) -> (k, XmlRpc.dump v)) pairs + | other -> raise (Type_error (XmlRpc.dump other)) + method new_page content publish = int_value (rpc#call "wp.newPage" @@ -354,6 +619,11 @@ object (self) map_array Post.of_xmlrpc (rpc#call "metaWeblog.getRecentPosts" (std_args @ [`Int num_posts])) + method get_post_status_list () = + match rpc#call "wp.getPostStatusList" std_args with + | `Struct pairs -> List.map (fun (k, v) -> (k, XmlRpc.dump v)) pairs + | other -> raise (Type_error (XmlRpc.dump other)) + method new_post content publish = int_value (rpc#call "metaWeblog.newPost" @@ -378,6 +648,47 @@ object (self) method get_authors () = map_array User.of_xmlrpc (rpc#call "wp.getAuthors" std_args) + method get_blogs () = + map_array Blog.of_xmlrpc (rpc#call "wp.getUsersBlogs" [`String username; + `String password]) + + method get_comment_count post_id = + CommentCount.of_xmlrpc + (rpc#call "wp.getCommentCount" (std_args @ [`Int post_id])) + + method get_comment_status_list () = + match rpc#call "wp.getCommentStatusList" std_args with + | `Struct pairs -> List.map (fun (k, v) -> (k, XmlRpc.dump v)) pairs + | other -> raise (Type_error (XmlRpc.dump other)) + + method get_comment comment_id = + Comment.of_xmlrpc + (rpc#call "wp.getComment" (std_args @ [`Int comment_id])) + + method get_comments ?(status="") ?(post_id=0) ?(offset=0) ?(number=10) () = + map_array Comment.of_xmlrpc + (rpc#call "wp.getComments" + (std_args @ [`Struct ["status", `String status; + "post_id", `Int post_id; + "offset", `Int offset; + "number", `Int number]])) + + method new_comment comment = + int_value + (rpc#call "wp.newComment" + (std_args @ [`Int comment.Comment.post_id; + Comment.to_xmlrpc comment])) + + method edit_comment comment_id comment = + ignore + (rpc#call "wp.editComment" + (std_args @ [`Int comment_id; + Comment.to_xmlrpc comment])) + + method delete_comment comment_id = + ignore + (rpc#call "wp.deleteComment" (std_args @ [`Int comment_id])) + method get_categories () = map_array Category.of_xmlrpc (rpc#call "wp.getCategories" std_args) @@ -393,6 +704,29 @@ object (self) rpc#call "wp.suggestCategories" (std_args @ [`String category; `Int max_results]) + method get_options names = + let result = + rpc#call + "wp.getOptions" + (std_args @ [`Array (List.map (fun s -> `String s) names)]) in + match result with + | `Struct pairs -> + List.map (fun (name, opt) -> (name, Option.of_xmlrpc opt)) pairs + | `Array [] -> [] + | other -> raise (Type_error (XmlRpc.dump other)) + + method set_options options = + let result = + rpc#call + "wp.setOptions" + (std_args @ [`Struct (List.map (fun (name, value) -> + (name, `String value)) options)]) in + match result with + | `Struct pairs -> + List.map (fun (name, opt) -> (name, Option.of_xmlrpc opt)) pairs + | `Array [] -> [] + | other -> raise (Type_error (XmlRpc.dump other)) + method upload_file ~name ~typ ~bits ~overwrite = let value = rpc#call "wp.uploadFile" @@ -406,7 +740,7 @@ object (self) | ("file", `String v) -> file := v | ("url", `String v) -> url := v | ("type", `String v) -> typ := v - | (field, _) -> raise (Unknown_field field)) + | (field, _) -> warn (Unknown_field field)) value; (!file, !url, !typ) end diff --git a/examples/wordpress/WordPress.mli b/examples/wordpress/WordPress.mli index 87b71dc..47b5a18 100644 --- a/examples/wordpress/WordPress.mli +++ b/examples/wordpress/WordPress.mli @@ -1,6 +1,6 @@ (* * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet - * Copyright (C) 2007 Dave Benjamin (dave@ramenlabs.com) + * Copyright (C) 2007-2009 Dave Benjamin (dave@ramenlabs.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,6 +20,21 @@ exception Type_error of string exception Unknown_field of string +val strict : bool ref + +module Blog : +sig + type t = { + mutable is_admin : bool; + mutable url : string; + mutable blog_id : int; + mutable blog_name : string; + mutable xmlrpc : string; + } + val make : unit -> t + val of_xmlrpc : XmlRpc.value -> t +end + module Category : sig type t = { @@ -34,6 +49,64 @@ sig val of_xmlrpc : XmlRpc.value -> t end +module CommentCount : +sig + type t = { + mutable approved : int; + mutable awaiting_moderation : int; + mutable spam : int; + mutable total_comments : int; + } + val make : unit -> t + val of_xmlrpc : XmlRpc.value -> t +end + +module Comment : +sig + type t = { + mutable date_created : XmlRpcDateTime.t; + mutable user_id : int; + mutable comment_id : int; + mutable parent : int; + mutable status : string; + mutable content : string; + mutable link : string; + mutable post_id : int; + mutable post_title : string; + mutable author : string; + mutable author_url : string; + mutable author_email : string; + mutable author_ip : string; + mutable typ : string; + } + val make : unit -> t + val of_xmlrpc : XmlRpc.value -> t + val to_xmlrpc : t -> XmlRpc.value +end + +module CustomField : +sig + type t = { + mutable id : int option; + mutable key : string option; + mutable value : string; + } + val make : unit -> t + val of_xmlrpc : XmlRpc.value -> t + val to_xmlrpc : t -> XmlRpc.value +end + +module Option : +sig + type t = { + mutable desc : string; + mutable readonly : bool; + mutable value : string; + } + val make : unit -> t + val of_xmlrpc : XmlRpc.value -> t +end + module User : sig type t = { @@ -83,6 +156,8 @@ sig mutable wp_page_order : int; mutable wp_author_id : int; mutable wp_author_display_name : string; + mutable custom_fields : CustomField.t list; + mutable wp_page_template : string; } val make : unit -> t val of_xmlrpc : XmlRpc.value -> t @@ -94,6 +169,7 @@ sig type t = { mutable user_id : int; mutable post_id : int; + mutable post_status : string; mutable date_created : XmlRpcDateTime.t; mutable description : string; mutable title : string; @@ -109,6 +185,7 @@ sig mutable wp_password : string; mutable wp_author_id : int; mutable wp_author_display_name : string; + mutable custom_fields : CustomField.t list; } val make : unit -> t val of_xmlrpc : XmlRpc.value -> t @@ -127,22 +204,37 @@ object val std_args : XmlRpc.value list val username : string method rpc : XmlRpc.client + method delete_comment : int -> unit method delete_page : int -> unit method delete_post : int -> unit + method edit_comment : int -> Comment.t -> unit method edit_page : int -> Page.t -> bool -> unit method edit_post : int -> Post.t -> bool -> unit method get_authors : unit -> User.t list + method get_blogs : unit -> Blog.t list method get_categories : unit -> Category.t list + method get_comment : int -> Comment.t + method get_comment_count : int -> CommentCount.t + method get_comment_status_list : unit -> (string * string) list + method get_comments : + ?status:string -> + ?post_id:int -> ?offset:int -> ?number:int -> unit -> Comment.t list + method get_options : string list -> (string * Option.t) list method get_page : int -> Page.t method get_page_list : unit -> PageListItem.t list + method get_page_status_list : unit -> (string * string) list + method get_page_templates : unit -> (string * string) list method get_pages : unit -> Page.t list method get_post : int -> Post.t + method get_post_status_list : unit -> (string * string) list method get_recent_posts : int -> Post.t list method new_category : name:string -> slug:string -> parent_id:int -> description:string -> int + method new_comment : Comment.t -> int method new_page : Page.t -> bool -> int method new_post : Post.t -> bool -> int + method set_options : (string * string) list -> (string * Option.t) list method suggest_categories : string -> int -> XmlRpc.value method upload_file : name:string -> diff --git a/examples/wordpress/test.ml b/examples/wordpress/test.ml index fe5b487..5bede7b 100644 --- a/examples/wordpress/test.ml +++ b/examples/wordpress/test.ml @@ -1,6 +1,6 @@ (* * XmlRpc Light, a small XmlRpc library based on Xml Light and Ocamlnet - * Copyright (C) 2007 Dave Benjamin (dave@ramenlabs.com) + * Copyright (C) 2007-2009 Dave Benjamin (dave@ramenlabs.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public |