# # add_file "config.make.in" # # add_file "configure.ac" # # add_file "ocaml.m4" # # patch "Makefile" # from [0486ba582193a4c7dcbd1d34b19643758bd68cb1] # to [468184ae6dd5fb915d9d1a1b6a64854cb829c38e] # # patch "README" # from [6a6a8ab967cbbfa28b2fc6e850289d5c3fc90aa5] # to [90c6b1e59affd24a1a0fcc844980140dd518e456] # # patch "agraph.ml" # from [ef0071477827ddaece72b04c821b5e77e90e1c11] # to [0249f50c3a735aa63a946d8b9bcaa6471cbd9027] # # patch "config.make.in" # from [] # to [f5c8ece6dbb2201a5a0d666c353b4b0346aa8f3a] # # patch "configure.ac" # from [] # to [43c8ff541d8d9b3c7a01992b0f3678649dcf001e] # # patch "database.ml" # from [87ffadd72ff3eabe54ccf02ed6bca4153299143e] # to [bfbc64267c32b93b83e8d14b1414352d0b6ddb6d] # # patch "database.mli" # from [4796fdb44abc125874a5de50a434019bf897266d] # to [0f26f7c44b6aad6c24d2ac7809d6ac8868bcbbaa] # # patch "glib/gspawn.ml" # from [be2cb8b8a4001b5acb7a292b25b19fd9a101d20a] # to [bfd9e189f852d27c821ac88b0e77d3485f2716c1] # # patch "glib/gspawn.mli" # from [9b0074abfd7c5494a41b430c15c8c7d324fafb83] # to [c43ee9e417dfec498f6b7fa63bfb6ba98257b410] # # patch "glib/ocaml-gspawn.c" # from [8f8b77c9930e734c9c2184481ea5bb368ccb3c16] # to [d7971112446d9d6b160a5ba3d902a6b32a256122] # # patch "icon.ml" # from [edf2e4191cf2c8f0494f1519246db3a5ad3c13ec] # to [15ec5abe4fbc3c4234d48c075d46ef10373568f8] # # patch "mlsqlite/ocaml-sqlite3.c" # from [8ebe955ccdc086a5feb0931c345495e922a1ded0] # to [4ffd05f56bd87954d1295b3b1fbd46e24de422cf] # # patch "ocaml.m4" # from [] # to [ec43df3f629049753f8f617e3b2702a9161ae48b] # # patch "ui.ml" # from [3fdb4ce3a783f75c399968e7a2ab62698d15c2ec] # to [7d827512c7a6b458a55372e159cfc7048e1ae789] # # patch "unidiff.ml" # from [2fa4f626d13a7b293abeb5ad72c388d69347a622] # to [27d78ed2191d1fb186ad09637874b4832c59b480] # # patch "view.ml" # from [8cffabcbe3db7aa326b6b5d20cc8ef48c2d7b49d] # to [8eedf028bdba7f8651a52f74647f88cd6bd75bac] # --- Makefile +++ Makefile @@ -1,17 +1,6 @@ -USE_NATIVE = true +include config.make -OCAMLC = ocamlc -OCAMLOPT = ocamlopt -OCAMLLEX = ocamllex -OCAMLYACC = ocamlyacc -OCAMLDEP = ocamldep -CAMLP4O = camlp4o - -MONOTONE_DIR := $(HOME)/src/monotone/monotone-mt -LABLGTK_DIR := $(HOME)/src/caml/lablgtk/lablgtk-no26/src -CRYPTO_LIB := /usr/lib/libcrypto.a - OCAMLNET := ocamlnet-0.97.1 EXTLIB := extlib-1.3 @@ -41,16 +30,15 @@ OBJ = $(patsubst %.ml,%.cmo,$(filter %.ml, $(SRC))) OBJX = $(patsubst %.ml,%.cmx,$(filter %.ml, $(SRC))) - -NAME = monotone-viz -VERSION = 0.9 -DISTSRC = Makefile monotone-viz.style.sample README NEWS \ +DISTSRC = Makefile configure.ac config.make.in ocaml.m4 configure aclocal.m4 \ + monotone-viz.style.sample README NEWS \ viz_misc.ml viz_misc.mli viz_types.ml viz_types.mli q.ml q.mli \ autocolor.ml autocolor.mli viz_style.ml viz_style.mli heap.ml heap.mli \ dot_types.mli dot_lexer.mll dot_parser.mly \ subprocess.ml subprocess.mli icon.ml status.ml ui.ml \ revision_types.mli revision_lexer.mll revision_parser.mly \ - database.ml database.mli unidiff.ml unidiff.mli view.ml view.mli main.ml \ + database.ml database.mli agraph.ml agraph.mli \ + unidiff.ml unidiff.mli view.ml view.mli main.ml \ mlsqlite/sqlite3.ml mlsqlite/sqlite3.mli mlsqlite/ocaml-sqlite3.c \ ocamlnet-0.97.1/base64.ml ocamlnet-0.97.1/base64.mli ocamlnet-0.97.1/LICENSE \ extlib-1.3/IO.ml extlib-1.3/IO.mli extlib-1.3/unzip.ml extlib-1.3/unzip.mli \ @@ -60,7 +48,7 @@ crypto/ocaml-openssl.c crypto/crypto.ml crypto/crypto.mli -ifdef USE_NATIVE +ifeq ($(OCAMLBEST), opt) monotone-viz : $(OBJX) lib3rdparty.a $(OCAMLOPT) -o $@ -I . -I $(LABLGTK_DIR) $(MLLIBS) $^ $(CRYPTO_LIB) monotone-viz : MLLIBS = str.cmxa lablgtk.cmxa gtkInit.cmx lablgnomecanvas.cmxa @@ -116,11 +104,15 @@ .PHONY : clean dist +ifeq ($OCAMLBEST, opt) +DEP_FLAGS = -native +endif + -include .depend .depend : $(SRC) @echo "making deps ..." - @$(OCAMLDEP) $(if $(USE_NATIVE),-native) $(addprefix -I ,$(VPATH)) $(filter-out $(USE_P4),$^) > $@ - @$(OCAMLDEP) $(if $(USE_NATIVE),-native) -pp '$(CAMLP4O)' $(USE_P4) >> $@ + @$(OCAMLDEP) $(DEP_FLAGS) $(addprefix -I ,$(VPATH)) $(filter-out $(USE_P4),$^) > $@ + @$(OCAMLDEP) $(DEP_FLAGS) -pp '$(CAMLP4O)' $(USE_P4) >> $@ dist : ../$(NAME)-$(VERSION).tar.gz ../$(NAME)-$(VERSION).tar.gz : $(DISTSRC) @@ -128,3 +120,8 @@ cd .. && mv "$$DIRNAME" $(NAME)-$(VERSION) && \ tar zcvf $(@F) $(addprefix $(NAME)-$(VERSION)/,$(DISTSRC)) && \ mv $(NAME)-$(VERSION) "$$DIRNAME" + +# not config.make +ifndef OCAMLLEX +$(error run ./configure first (cf README)) +endif --- README +++ README @@ -15,14 +15,18 @@ To compile from sources, you'll also need: - a compiled monotone source tree - ocaml compiler (>= 3.07) -- LablGTK 2.4.0 or lablgtk-20041119 +- LablGTK 2.4.0 or lablgtk-20041119 or lablgtk-20050218 - libcrypto, from the openssl toolkit COMPILING ========= - compile/install ocaml and LablGTK -- adjust the MONOTONE_DIR, LABLGTK_DIR and CRYPTO_LIB variables in Makefile +- if you've pulled this from the monotone repository, + run `aclocal -I . && autoconf' to generate configure +- run ./configure, with the following options if needed : + --with-monotone-dir + --with-lablgtk-dir - make - install the binary monotone-viz somewhere @@ -38,10 +42,7 @@ MT/ subdirectory), it will automatically use the database and branch specified in the MT/options file. -Set the MONOTONE environment variable to the name of the monotone -executable if it is not `monotone' or cannot be found in the PATH. - STYLE FILE ========== Appearance can be controlled via a style file, named @@ -51,8 +52,6 @@ grammar: "font" "cert" cert_name "[" ( attribute "=" ";" )+ "]" - "bibble_babble" - "short_labels" "autocolor" "layout" comments are delimited by "(*" and "*)" --- agraph.ml +++ agraph.ml @@ -47,6 +47,7 @@ !+ "digraph \"monotone-viz\"\n{\n" ; if params.lr_layout then !+ " graph [rankdir=LR] ;\n" ; + !+ " graph [ranksep=\"0.25\"] ;\n" ; !+ " node [label=\"\"] ;\n" ; begin --- config.make.in +++ config.make.in @@ -0,0 +1,16 @@ +# -*- makefile -*- + +OCAMLBEST = @OCAMLBEST@ +OCAMLC = @OCAMLC@ +OCAMLOPT = @OCAMLOPT@ +OCAMLLEX = @OCAMLLEX@ +OCAMLYACC = @OCAMLYACC@ +OCAMLDEP = @OCAMLDEP@ +CAMLP4O = @CAMLP4O@ + +MONOTONE_DIR := @MONOTONE_DIR@ +LABLGTK_DIR := @LABLGTK_DIR@ +CRYPTO_LIB := /usr/lib/libcrypto.a + +NAME := @PACKAGE_NAME@ +VERSION := @PACKAGE_VERSION@ --- configure.ac +++ configure.ac @@ -0,0 +1,63 @@ +AC_INIT(monotone-viz, 0.9) + +AC_PROG_OCAML +AC_PROG_OCAML_TOOLS +AC_PROG_CAMLP4 + +# Check LablGTK +AC_ARG_WITH([lablgtk-dir], + AS_HELP_STRING([--with-lablgtk-dir], + [specify location of lablgtk library]), + LABLGTK_DIR=$withval) +AC_CHECK_OCAML_MODULE(lablgtk, LABLGTK_DIR, GFile, +lablgtk2 +lablgtk) +# Stop if LablGTK is not found +if test -z "$LABLGTK_DIR" ; then + AC_MSG_ERROR([ + +Could not find LablGTK. Make sure LablGTK >= 2.4.0 is installed and +specify its location to configure with the `--with-lablgtk-dir' +option.]) +fi +LABLGTK_DIR=$(echo $LABLGTK_DIR | sed "address@hidden@$OCAMLLIB/@") +# Check if LablGTK was compiled with libgnomecanvas support +AC_MSG_CHECKING([GnomeCanvas support]) +if test -r "$LABLGTK_DIR/lablgnomecanvas.cma" ; then + AC_MSG_RESULT(found) +else + AC_MSG_ERROR([ + +libgnomecanvas support not found. +LablGTK need to be built with GnomeCanvas support.]) +fi +# Check if LablGTK is natively compiled +if test -r "$LABLGTK_DIR/lablgtk.cmxa" -a -r "$LABLGTK_DIR/lablgnomecanvas.cmxa"; then + echo [Using the native code compiler] +else + echo [Using the byte code compiler] + OCAMLBEST=byte +fi + + +# Check the sqlite3 sources +AC_ARG_WITH([monotone-dir], + AS_HELP_STRING([--with-monotone-dir], + [specify location of monotone build tree]), + MONOTONE_DIR=$withval, + MONOTONE_DIR=monotone) +AC_MSG_CHECKING(sqlite sources) +if test -d "$MONOTONE_DIR" -a -r "$MONOTONE_DIR/sqlite/lib3rdparty_a-main.o" ; then + AC_MSG_RESULT(found in $MONOTONE_DIR/sqlite) +else + AC_MSG_ERROR([ + +Could not find compiled sqlite sources. Monotone-viz needs a compiled +monotone tree for the sqlite library. Create a link named `monotone' +or specify the location to configure using the `--with-monotone-dir' +option.]) +fi +if test "${MONOTONE_DIR:0:1}" != "/" ; then + MONOTONE_DIR=$PWD/$MONOTONE_DIR +fi +AC_SUBST(MONOTONE_DIR) + +AC_OUTPUT(config.make) --- database.ml +++ database.ml @@ -150,13 +150,15 @@ agraph | _ -> (* we need another database query *) - Sqlite3.fetch db + Sqlite3.fetch_f db + process_branching_edge_row agraph "SELECT A.parent, A.child \ FROM revision_ancestry AS A, revision_certs AS C, revision_certs AS P \ - WHERE C.id = A.child AND P.id = A.parent AND \ + WHERE (C.id IN %s OR P.id IN %s) AND \ + C.id = A.child AND P.id = A.parent AND \ C.name = 'branch' AND P.name = 'branch' AND \ C.value != P.value" - process_branching_edge_row agraph + view_name view_name end in agraph @@ -371,15 +373,22 @@ let (_, rowid) = Hashtbl.find pubkeys id in rowid -let get_matching_tags db p = +let get_matching_cert db name p = List.rev (Sqlite3.fetch_f db.db (fun acc -> function - | [| id; tag |] when p tag -> (id, tag) :: acc + | [| id; v |] when p v -> (id, v) :: acc | _ -> acc) [] - "SELECT id, unbase64(value) FROM revision_certs WHERE name = 'tag'") + "SELECT id, unbase64(value) FROM revision_certs WHERE name = '%s'" name) +let get_matching_tags db p = + get_matching_cert db "tag" p + +let get_matching_dates db d_pref = + get_matching_cert db "date" + (string_is_prefix d_pref) + let run_monotone_diff db monotone_exe edge status cb = ignore (spawn_monotone_diff db.filename monotone_exe edge status cb) --- database.mli +++ database.mli @@ -18,7 +18,8 @@ val fetch_cert_signer : t -> string -> string -> string list val fetch_cert_value : t -> string -> string -> string list -val get_matching_tags : t -> (string -> bool) -> (string * string) list +val get_matching_tags : t -> (string -> bool) -> (string * string) list +val get_matching_dates : t -> string -> (string * string) list val get_key_rowid : t -> string -> int --- glib/gspawn.ml +++ glib/gspawn.ml @@ -80,7 +80,11 @@ ?child_setup:(unit -> unit) -> flags:spawn_flags list -> string list -> status * string * string = "ml_g_spawn_sync" - + +external command_line_sync : + string -> status * string * string = "ml_g_spawn_command_line_sync" +external command_line_async : string -> unit = "ml_g_spawn_command_line_async" + type source_id external add_child_watch : ?prio:int -> pid -> (int -> unit) -> source_id = "ml_g_add_child_watch_full" external remove_watch : source_id -> unit = "ml_g_source_remove" --- glib/gspawn.mli +++ glib/gspawn.mli @@ -68,6 +68,13 @@ external close_pid : pid -> unit = "ml_g_spawn_close_pid" +external command_line_sync : + string -> status * string * string = "ml_g_spawn_command_line_sync" +(** @raise Error if the spawn fails *) + +external command_line_async : string -> unit = "ml_g_spawn_command_line_async" +(** @raise Error if the spawn fails *) + type source_id external add_child_watch : ?prio:int -> pid -> (int -> unit) -> source_id = "ml_g_add_child_watch_full" external remove_watch : source_id -> unit = "ml_g_source_remove" --- glib/ocaml-gspawn.c +++ glib/ocaml-gspawn.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "wrappers.h" #include "ml_glib.h" @@ -161,6 +162,26 @@ return r; } +static value +convert_sync_status (int exit_status, gchar *standard_output, gchar *standard_error) +{ + CAMLparam0(); + CAMLlocal4(res, status, out, err); + + status = convert_exit_status (exit_status); + out = copy_string (standard_output ? standard_output : ""); + g_free (standard_output); + err = copy_string (standard_error ? standard_error : ""); + g_free (standard_error); + + res = alloc_small (3, 0); + Field (res, 0) = status; + Field (res, 1) = out; + Field (res, 2) = err; + + CAMLreturn (res); +} + CAMLprim value ml_g_spawn_sync (value o_working_directory, value o_envp, @@ -186,6 +207,7 @@ standard_output = NULL; standard_error = NULL; + caml_enter_blocking_section (); g_spawn_sync (working_directory, argv, envp, @@ -196,6 +218,7 @@ &standard_error, &exit_status, &error); + caml_leave_blocking_section (); g_free (working_directory); g_strfreev (argv); @@ -204,35 +227,55 @@ if (error) ml_raise_gerror (error); - { - CAMLparam0(); - CAMLlocal4(res, status, out, err); - - status = convert_exit_status (exit_status); - if (standard_output != NULL) - { - out = copy_string (standard_output); - g_free (standard_output); - } - else - out = copy_string (""); - if (standard_error != NULL) - { - err = copy_string (standard_error); - g_free (standard_error); - } - else - err = copy_string (""); + return convert_sync_status (exit_status, standard_output, standard_error); +} - res = alloc_small (3, 0); - Field (res, 0) = status; - Field (res, 1) = out; - Field (res, 2) = err; +CAMLprim value +ml_g_spawn_command_line_sync (value cmd) +{ + GError *error = NULL; + gchar *command; + gchar *standard_output; + gchar *standard_error; + gint exit_status; - CAMLreturn (res); - } + standard_output = NULL; + standard_error = NULL; + + command = copy_caml_string (cmd); + caml_enter_blocking_section (); + g_spawn_command_line_sync (command, + &standard_output, + &standard_error, + &exit_status, + &error); + caml_leave_blocking_section (); + g_free (command); + + if (error) + ml_raise_gerror (error); + + return convert_sync_status (exit_status, standard_output, standard_error); } +CAMLprim value +ml_g_spawn_command_line_async (value cmd) +{ + GError *error = NULL; + gchar *command; + + command = copy_caml_string (cmd); + caml_enter_blocking_section (); + g_spawn_command_line_async (command, &error); + caml_leave_blocking_section (); + g_free (command); + + if (error) + ml_raise_gerror (error); + + return Val_unit; +} + #if defined (G_OS_UNIX) # define GPid_val(v) (GPid)Int_val(v) #elif defined (G_OS_WIN32) --- icon.ml +++ icon.ml @@ -1,173 +1,55 @@ (* XPM *) let monotone_xpm = [| -(* columns rows colors chars-per-pixel *) -"24 32 133 2"; -" c black"; -". c #1C1A22"; -"X c #35303F"; -"o c #373140"; -"O c #3C3646"; -"+ c #464053"; -"@ c #50485E"; -"# c #5A526A"; -"$ c #665C77"; -"% c #2B4E98"; -"& c #2D509A"; -"* c #4664A4"; -"= c #536FAA"; -"- c #5471AC"; -"; c #776C8C"; -": c #657EB3"; -"> c #7187B6"; -"; c #7C8FBB"; -"< c #7D92BE"; -"1 c #807497"; -"2 c #827699"; -"3 c #8A7CA1"; -"4 c #967FA0"; -"5 c #8D80AD"; -"6 c #9582A5"; -"7 c #9483AC"; -"8 c #9983A6"; -"9 c #9C8DAF"; -"0 c #9687B4"; -"q c #9688B3"; -"w c #9B8BB4"; -"e c #9B8CB9"; -"r c #9D91B5"; -"t c #9E90BB"; -"y c #A183A2"; -"u c #A38AAB"; -"i c #AA8AAA"; -"p c #A18CB2"; -"a c #A091AF"; -"s c #AA9BAE"; -"d c #A093B4"; -"f c #A091BC"; -"g c #A79ABC"; -"h c #AA9FBB"; -"j c #B586A2"; -"k c #BD8DA6"; -"l c #BA8DAA"; -"z c #B298AA"; -"x c #BF91AC"; -"c c #BB9FB0"; -"v c #AEA4BC"; -"b c #B3A0B4"; -"n c #B0A4BE"; -"m c #BBAFBE"; -"M c #8FA0C4"; -"N c #96A6C6"; -"B c #A495C1"; -"V c #A798C4"; -"C c #A899C6"; -"Z c #AA9AC8"; -"A c #A4B1CD"; -"S c #ADB8CF"; -"D c #AEB9D1"; -"F c #B2A9C4"; -"G c #B4AACA"; -"H c #B8AECC"; -"J c #B9B1C5"; -"K c #BDB5CB"; -"L c #BDB9C7"; -"P c #B1BAD2"; -"I c #BBC5DB"; -"U c #C4859D"; -"Y c #C18DA6"; -"T c #CB8BA1"; -"R c #C193AD"; -"E c #CA91A6"; -"W c #CE95AB"; -"Q c #D490A5"; -"! c #D197AC"; -"~ c #D39AAD"; -"^ c #DD95A9"; -"/ c #D99AAC"; -"( c #DD9DB2"; -") c #C3B1BD"; -"_ c #DDAEBC"; -"` c #D3B0BB"; -"' c #E095AA"; -"] c #E19FB4"; -"[ c #E99FB4"; -"{ c #E7A0B4"; -"} c #EBA3B6"; -"| c #EDA5B8"; -" . c #F0A1B4"; -".. c #F0A6B9"; -"X. c #F3A8BA"; -"o. c #C5BBC5"; -"O. c #C1BBCC"; -"+. c #CFB8C2"; -"@. c #CABFC8"; -"#. c #D1BAC4"; -"$. c #CAC1CB"; -"%. c #C0C8D9"; -"&. c #D1C9CE"; -"*. c #D1CDD5"; -"=. c #D9CAD1"; -"-. c #D5D1D6"; -";. c #D9D6DB"; -":. c #DBD9DD"; -">. c #C3CDE2"; -";. c #CED5E2"; -"<. c #D0D5E1"; -"1. c #D6DAE3"; -"2. c #D6DDE8"; -"3. c #D9DBE2"; -"4. c #D9DFE9"; -"5. c #DCE0E6"; -"6. c #DCE1EC"; -"7. c #E4D2D6"; -"8. c #E0D5DA"; -"9. c #E1DEE0"; -"0. c #F1DDE1"; -"q. c #E1E2E5"; -"w. c #E2E5EB"; -"e. c #E4E8EA"; -"r. c #E8E7E7"; -"t. c #ECECEC"; -"y. c #EFF0EE"; -"u. c #F0EFEE"; -"i. c #F1F0EE"; -"p. c #F2F3F1"; -"a. c #F4F8F5"; -"s. c #F8F5F1"; -"d. c None"; -(* pixels *) -"d.= A P D P P P P P P D P D P P P P P D P P > = "; -"* N w.q.q.w.q.q.w.5.q.q.q.w.q.w.w.q.w.e.e.r.I < "; -"N 5.i.i.a.t.t.y.y.y.y.r.y.t.t.t.t.t.i.#.=.t.p.%."; -"D q.a.#.c t.t.t.t.y.y.p.a.p.i.y.e.p.#.^ Q ;.p.;."; -"D e.8./ ^ 8.a.i.r.r.r.o.s m -.9.s.e.~ } ..E ;.1."; -"D t.7.' | / $.v 6 r r 7 7 5 6 8 L ) ^ } ..U $.4."; -"P e.0.} } } Q 8 t f f f f f f f 5 j .[ ..T o.2."; -"D e.7.' } } X.R e f f f t f f f p _ ..[ | T o.2."; -"S e.8._ ..} ..R e f f f f t f f e l ..} ..T $.2."; -"D e.o.i } | } i e f f f f f f f f w W X.[ _ e.<."; -"P 3.6 w R X.( w f f f f t f f f f e w ! .` p.<."; -"P 5.d e w ! W e f f f f f f f f f f f p Y z i.<."; -"P e.g e f p u e f f f f f f f f f f f f 0 G i.<."; -"P e.a f f f e f f f f f f f f f f f f f e G s.<."; -"D e.J 0 f f f f f f f f t f t f f f f f e H i.<."; -"D e.9.d f f f f f f f f f f f f f B f f w O.p.<."; -"P q.a.L w t e f B f f f f f f f f q f f e J p.<."; -"P q.i.r.J e B q O 3 B p t f f V 3 . ; V e O.i.<."; -"P e.y.y.e.f V 2 @ Z f t e e C + ; Z w :.i.<."; -"P w.y.r.p.$.e e o o f f f f t B $ # f V 7 ;.p.<."; -"P q.y.r.t.t.h e B e f t f f f f V C f e r r.i.<."; -"P r.y.t.t.t.;.r e t B t f f f f t t w 9 -.i.t.<."; -"P q.y.t.t.t.i.*.w e t f f f f f w e G q.y.t.u.<."; -"P w.y.t.t.t.t.r.F w 4 f f f f 6 7 w -.a.e.t.t.<."; -"P w.y.t.t.t.t.y.L e u u w q w y f w -.i.t.t.i.<."; -"P r.y.y.t.t.t.y.:.r e x ~ { W u e n i.t.t.t.t.<."; -"P q.y.r.t.t.t.t.y.v 0 x X.| | w f ;.u.e.t.e.u.<."; -"P q.y.t.t.t.t.t.p.3.t l X.| | 8 O.p.t.t.t.u.t.<."; -"D q.t.t.t.t.t.t.t.u.3.c T / k F t.t.t.t.t.t.t.<."; -"M 4.s.u.t.i.i.t.u.u.i.u.*.&.-.u.u.u.u.u.u.i.i.I "; -"% , 1.1.2.2.1.1.2.2.1.4.q.4.4.4.1.4.1.1.2.3.D : "; -"d.>.6.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.,.>." +"25 32 17 1"; +" c None"; +". c #040606"; +"+ c #443E50"; +"@ c #5F5269"; +"# c #695E7B"; +"$ c #8D7EA4"; +"% c #9C7F9D"; +"& c #A48AAD"; +"* c #9F8EB5"; +"= c #9D91B0"; +"- c #9E92BE"; +"; c #B78EAB"; +"> c #AB98B2"; +", c #C890A5"; +"' c #DE9DB0"; +") c #EEA2B6"; +"! c #EAA5B6"; +" "; +" ,!' "; +" !' !)), "; +" ,)!, $-- ,)))! "; +" )))),%---------- !)))) "; +" )))!!,*---------*;!)))) "; +" ,)!!!'*---------*,!!))! "; +" !!!!'*----------&!!!)! "; +" ;!!!,*-----------;!!)' "; +" -*'!!;------------*;!!, "; +" --&'!&--------------;' "; +" ---&,---------------*& "; +" ----*------------------ "; +" ----------------------- "; +" ---------------------- "; +" ---------------------* "; +" =-------------------- "; +" *---$#--------*+#--- "; +" *--+.$-------#.+--- "; +" address@hidden@--- "; +" *-*+#-------$$--- "; +" >---------------- "; +" =--------------$ "; +" =------------* "; +" >-*%-----*$-* "; +" =-%&---*%-- "; +" >-*;&;;;&-- "; +" *-;'!!'*- "; +" =-;!!!'*- "; +" =;!!!'** "; +" %''';= "; +" " |] let monotone = lazy (GdkPixbuf.from_xpm_data monotone_xpm) --- mlsqlite/ocaml-sqlite3.c +++ mlsqlite/ocaml-sqlite3.c @@ -225,7 +225,7 @@ if (Is_exception_result (accum)) { sqlite3_free (errmsg); /* should be NULL actually */ - mlraise (accum); + mlraise (Extract_exception (accum)); } else ml_sqlite3_raise_exn (status, errmsg, FALSE); --- ocaml.m4 +++ ocaml.m4 @@ -0,0 +1,209 @@ +dnl -*- autoconf -*- macros for OCaml +dnl by Olivier Andrieu +dnl from a configure.in by Jean-Christophe Filliâtre, +dnl from a first script by Georges Mariano +dnl +dnl defines AC_PROG_OCAML that will check the OCaml compiler +dnl and set the following variables : +dnl OCAMLC "ocamlc" if present in the path, or a failure +dnl or "ocamlc.opt" if present with same version number as ocamlc +dnl OCAMLOPT "ocamlopt" (or "ocamlopt.opt" if present), or unset +dnl OCAMLBEST either "byte" if no native compiler was found, +dnl "opt" otherwise +dnl OCAMLDEP "ocamldep" +dnl OCAMLLIB the path to the ocaml standard library +dnl OCAMLVERSION the ocaml version number +dnl +dnl OCAMLMKTOP +dnl OCAMLMKLIB +dnl OCAMLDOC +AC_DEFUN([AC_PROG_OCAML], +[dnl +# checking for ocamlc +AC_CHECK_PROG(OCAMLC,ocamlc,ocamlc,AC_MSG_ERROR(Cannot find ocamlc.)) +OCAMLVERSION=$($OCAMLC -version) +AC_MSG_RESULT(OCaml version is $OCAMLVERSION) +OCAMLLIB=$($OCAMLC -where) +AC_MSG_RESULT(OCaml library path is $OCAMLLIB) +# checking for ocamlopt +AC_CHECK_PROG(OCAMLOPT,ocamlopt,ocamlopt) +OCAMLBEST=byte +if test -z "$OCAMLOPT"; then + AC_MSG_WARN(Cannot find ocamlopt; bytecode compilation only.) +else + TMPVERSION=$($OCAMLOPT -version) + if test "$TMPVERSION" != "$OCAMLVERSION" ; then + AC_MSG_RESULT(versions differs from ocamlc; ocamlopt discarded.) + unset OCAMLOPT + else + OCAMLBEST=opt + fi +fi +# checking for ocamlc.opt +AC_CHECK_PROG(OCAMLCDOTOPT,ocamlc.opt,ocamlc.opt) +if test "$OCAMLCDOTOPT"; then + TMPVERSION=$($OCAMLCDOTOPT -version) + if test "$TMPVERSION" != "$OCAMLVERSION" ; then + AC_MSG_RESULT(versions differs from ocamlc; ocamlc.opt discarded.) + else + OCAMLC=$OCAMLCDOTOPT + fi +fi +# checking for ocamlopt.opt +if test "$OCAMLOPT" ; then + AC_CHECK_PROG(OCAMLOPTDOTOPT,ocamlopt.opt,ocamlopt.opt) + if test "$OCAMLOPTDOTOPT"; then + TMPVERSION=$($OCAMLOPTDOTOPT -version) + if test "$TMPVERSION" != "$OCAMLVERSION" ; then + AC_MSG_RESULT(version differs from ocamlc; ocamlopt.opt discarded.) + else + OCAMLOPT=$OCAMLOPTDOTOPT + fi + fi +fi +# checking for ocamldep +AC_CHECK_PROG(OCAMLDEP,ocamldep,ocamldep,AC_MSG_ERROR(Cannot find ocamldep.)) + +#checking for ocamlmktop +AC_CHECK_PROG(OCAMLMKTOP,ocamlmktop,ocamlmktop, AC_MSG_WARN(Cannot find ocamlmktop.)) +#checking for ocamlmklib +AC_CHECK_PROG(OCAMLMKLIB,ocamlmklib,ocamlmklib, AC_MSG_WARN(Cannot find ocamlmklib.)) +# checking for ocamldoc +AC_CHECK_PROG(OCAMLDOC,ocamldoc,ocamldoc, AC_MSG_WARN(Cannot find ocamldoc.)) + +# get the C compiler used by ocamlc +if test -z "$CC" ; then + touch conftest.c + CC=$($OCAMLC -verbose conftest.c 2>&1 | awk '/^+/ {print $[]2 ; exit}') + echo OCaml uses $CC to compile C files +fi + +AC_SUBST(OCAMLC) +AC_SUBST(OCAMLOPT) +AC_SUBST(OCAMLDEP) +AC_SUBST(OCAMLBEST) +AC_SUBST(OCAMLVERSION) +AC_SUBST(OCAMLLIB) +AC_SUBST(OCAMLMKLIB) +AC_SUBST(OCAMLMKTOP) +AC_SUBST(OCAMLDOC) +]) +dnl +dnl +dnl +dnl macro AC_PROG_OCAML_TOOLS will check OCamllex and OCamlyacc : +dnl OCAMLLEX "ocamllex" or "ocamllex.opt" if present +dnl OCAMLYACC "ocamlyac" +AC_DEFUN([AC_PROG_OCAML_TOOLS], +[dnl +# checking for ocamllex and ocamlyacc +AC_CHECK_PROG(OCAMLLEX,ocamllex,ocamllex,AC_MSG_ERROR(Cannot find ocamllex.)) +if test "$OCAMLLEX"; then + AC_CHECK_PROG(OCAMLLEXDOTOPT,ocamllex.opt,ocamllex.opt) + if test "$OCAMLLEXDOTOPT"; then + OCAMLLEX=$OCAMLLEXDOTOPT + fi +else + AC_MSG_ERROR(Cannot find ocamllex.) +fi +AC_CHECK_PROG(OCAMLYACC,ocamlyacc,ocamlyacc,AC_MSG_ERROR(Cannot find ocamlyacc.)) +AC_SUBST(OCAMLLEX) +AC_SUBST(OCAMLYACC) +]) +dnl +dnl +dnl +dnl AC_PROG_CAMLP4 checks for Camlp4 +AC_DEFUN([AC_PROG_CAMLP4], +[dnl +AC_REQUIRE([AC_PROG_OCAML]) +# checking for camlp4 +AC_CHECK_PROG(CAMLP4,camlp4,camlp4) +if test "$CAMLP4"; then + TMPVERSION=$($CAMLP4 -v 2>&1| sed -n -e 's|.*version *\(.*\)$|\1|p') + if test "$TMPVERSION" != "$OCAMLVERSION" ; then + AC_MSG_ERROR(versions differs from ocamlc) + else + AC_CHECK_PROG(CAMLP4O,camlp4o,camlp4o) + fi +fi +AC_SUBST(CAMLP4) +AC_SUBST(CAMLP4O) +]) +dnl +dnl +dnl +dnl macro AC_PROG_FINDLIB will check for the presence of +dnl ocamlfind if configure is called with --with-findlib +AC_DEFUN([AC_PROG_FINDLIB], +[dnl +AC_ARG_WITH(findlib,[ --with-findlib use findlib package system], + use_findlib="$withval") +# checking for ocamlfind +if test "$use_findlib" = yes ; then + AC_CHECK_PROG(OCAMLFIND,ocamlfind,ocamlfind, + AC_MSG_ERROR(ocamlfind not found)) +else + unset OCAMLFIND +fi +AC_SUBST(OCAMLFIND) +]) +dnl +dnl +dnl +dnl AC_CHECK_OCAML_PKG checks wether a findlib package is present +dnl defines pkg_name to name +AC_DEFUN([AC_CHECK_OCAML_PKG], +[dnl +AC_REQUIRE([AC_PROG_FINDLIB]) +if test "$use_findlib" = yes ; then + AC_MSG_CHECKING(findlib package $1) + if $OCAMLFIND query $1 >/dev/null 2>/dev/null; then + AC_MSG_RESULT(found) + pkg_$1="$1" + else + AC_MSG_WARN(not found) + unset pkg_$1 + fi +fi +]) +dnl +dnl +dnl +dnl AC_ARG_OCAML_INSTALLDIR adds a --with-installdir option +AC_DEFUN([AC_ARG_OCAML_INSTALLDIR], +[dnl +AC_ARG_WITH(installdir,[ --with-installdir=DIR specify installation directory],INSTALLDIR="$withval") +if ! test "$INSTALLDIR" -o "$use_findlib" ; then + INSTALLDIR='$(OCAMLLIB)/$(NAME)' +fi +AC_SUBST(INSTALLDIR) +]) +dnl +dnl +dnl +dnl AC_CHECK_OCAML_MODULE looks for a module in a given path +dnl 1 -> name (for printing) +dnl 2 -> env var name +dnl 3 -> module to check +dnl 4 -> default dirs +AC_DEFUN([AC_CHECK_OCAML_MODULE], +[dnl +AC_MSG_CHECKING($1 directory) +cat > conftest.ml < /dev/null 2>&1 ; then + found=yes + break + fi +done +if test "$found" ; then + AC_MSG_RESULT($$2) +else + AC_MSG_RESULT(not found) + unset $2 +fi +AC_SUBST($2)]) --- ui.ml +++ ui.ml @@ -70,7 +70,7 @@ add "Certs" ~label:"Display certs" ; add "Diff_one" ~label:"Diff with ancestor" ; add "Diff_many" ~label:"Diff with ancestor" ; - add "Diff_other" ~label:"Diff with other node" ; + add "Diff_other" ~label:"Diff with selected node" ; add "Copy_revision" ~label:"Copy revision id to the clipboard" ; add "Copy_manifest" ~label:"Copy manifest id to the clipboard" ] ; let g_view = GAction.action_group ~name:"view" () in @@ -230,7 +230,7 @@ ~xalign:0. ~packing () in let al = GBin.alignment ~border_width:8 ~packing () in - al#set_left_padding 16 ; + al#misc#set_property "left-padding" (`INT 16) ; (GPack.vbox ~packing:al#add ())#pack let make v () = --- unidiff.ml +++ unidiff.ml @@ -105,6 +105,7 @@ let window = GWindow.dialog ~no_separator:true ?parent ~title:"Monotone diff output" + ~type_hint:`NORMAL ~icon:(Lazy.force Icon.monotone) () in window#add_button_stock `SAVE `SAVE ; window#add_button_stock `CLOSE `CLOSE ; --- view.ml +++ view.ml @@ -357,6 +357,12 @@ ~label:"Include sub-branches" ~active:false ~packing:hb#pack () in let entry = GEdit.entry ~packing:(hb#pack ~from:`END) () in + begin + let tooltips = GData.tooltips () in + tooltips#set_tip + ~text:"Find a node by its revision id, tag or date (YYYY-MM-DD)" + entry#coerce + end ; let lbl = GMisc.label ~text:"Find:" ~packing:(hb#pack ~from:`END) () in let c = { combo = combo ; combo_signal = None ; @@ -854,18 +860,30 @@ then (k, n) :: acc else acc) nodes [] - let locate_tag v re = + let is_date = + let re = Str.regexp "[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$" in + fun id -> Str.string_partial_match re id 0 + + let locate_with_db v f = let g = some v.agraph in - let db = Agraph.get_db g in List.map (fun (id, _) -> id, get_cnode v id) (List.sort (fun (_,a) (_,b) -> compare a b) (List.filter (fun (id, _) -> Agraph.mem g id) - (Database.get_matching_tags db - (fun v -> Str.string_match re v 0)))) + (f (Agraph.get_db g)))) + let locate_date v date_prefix = + locate_with_db v + (fun db -> Database.get_matching_dates db date_prefix) + + let locate_tag v re = + locate_with_db v + (fun db -> + Database.get_matching_tags db + (fun t -> Str.string_match re t 0)) + let locate v q = match v.find.last_find with | (last_q, n :: t) when last_q = q -> @@ -875,6 +893,8 @@ let candidates = if is_id q then locate_id v q + else if is_date q + then locate_date v q else try locate_tag v (Str.regexp q) with Failure _ -> [] in