[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

o_fubar.ml -- Ocaml (is (not)) FUBAR



Hi all,
  I've written a small toy that perform consistency checks on a set of
ocaml bytecode objects (.cmo and .cma). Checks are performed usings
md5sums kept inside them as reported by objinfo.

Intented usage for us is to ensure that an ocaml library package upload
doesn't mess up other libraries due to interface incompatibilities. The
idea is to run it after having locally installed a new library package.
o_fubar should be able to find all possibly "inconsistent assumption
over ..." compiler error.

Obviously it works only for libraries that the DD has currently
installed so you are encouraged to install all the ocaml stuff :-)

o_fubar.ml is attached and can be run as an ocaml script. It requires
findlib, pcre and objinfo.

Sample usage to check consistency of your ocaml standard library:

$ find `ocamlfind printconf stdlib` -name '*.cm[ao]' | ./o_fubar.ml -
Inconsistent assumptions over GMain:
  Objects that believe GMain has md5sum d76ddfca17bc0653ef15c76321c1460d:
    /usr/lib/ocaml/3.06/lablgtk/lablgtk.cma
  Objects that believe GMain has md5sum 0ee4ed600e39dca37ba934c585e50833:
    /usr/lib/ocaml/3.06/cameleon/topcameleon.cma
    /usr/lib/ocaml/3.06/cameleon/configwin.cma
    /usr/lib/ocaml/3.06/cameleon/ocamlcvs.cma
    /usr/lib/ocaml/3.06/cameleon/mlchat.cma
    /usr/lib/ocaml/3.06/cameleon/cam_toplevel.cmo
Inconsistent assumptions over Shell:
  Objects that believe Shell has md5sum 94ea6aa45ac0cd167fac7e34965a9a2f:
    /usr/lib/ocaml/3.06/shell/shell.cma
  Objects that believe Shell has md5sum 6aaa60883bba1a84e1b1c8ed814b5308:
    /usr/lib/ocaml/3.06/labltk/jpflib.cma
Inconsistent assumptions over Image:
  Objects that believe Image has md5sum 91476626c66fc76e7acec6ea36ad59f4:
    /usr/lib/ocaml/3.06/camlimages/ci_xvthumb.cma
    /usr/lib/ocaml/3.06/camlimages/ci_xpm.cma
    /usr/lib/ocaml/3.06/camlimages/ci_tiff.cma
    /usr/lib/ocaml/3.06/camlimages/ci_ps.cma
    /usr/lib/ocaml/3.06/camlimages/ci_ppm.cma
    /usr/lib/ocaml/3.06/camlimages/ci_png.cma
    /usr/lib/ocaml/3.06/camlimages/ci_lablgtk.cma
    /usr/lib/ocaml/3.06/camlimages/ci_jpeg.cma
    /usr/lib/ocaml/3.06/camlimages/ci_graphics.cma
    /usr/lib/ocaml/3.06/camlimages/ci_gif.cma
    /usr/lib/ocaml/3.06/camlimages/ci_freetype.cma
    /usr/lib/ocaml/3.06/camlimages/ci_core.cma
    /usr/lib/ocaml/3.06/camlimages/ci_bmp.cma
  Objects that believe Image has md5sum 5384df8eda00defb643357d333c4cfb4:
    /usr/lib/ocaml/3.06/labltk/labltk.cma
Inconsistent assumptions over GtkMain:
  Objects that believe GtkMain has md5sum aff5bf3f637c79537e1df5844fbef3d1:
    /usr/lib/ocaml/3.06/lablgtk/gtkInit.cmo
    /usr/lib/ocaml/3.06/lablgtk/gtkThread.cmo
    /usr/lib/ocaml/3.06/lablgtk/lablglade.cma
    /usr/lib/ocaml/3.06/lablgtk/lablgtk.cma
  Objects that believe GtkMain has md5sum 6a5ad769187ae6b67bc5dca9f66a53b8:
    /usr/lib/ocaml/3.06/cameleon/topcameleon.cma
    /usr/lib/ocaml/3.06/cameleon/configwin.cma
    /usr/lib/ocaml/3.06/cameleon/ocamlcvs.cma
    /usr/lib/ocaml/3.06/cameleon/mlchat.cma
    /usr/lib/ocaml/3.06/cameleon/cam_toplevel.cmo
Inconsistent assumptions over Pa_extend:
  Objects that believe Pa_extend has md5sum 6f6267d8155ea57dd34369c019b58e69:
    /usr/lib/ocaml/3.06/camlp4/pa_extfold.cmo
  Objects that believe Pa_extend has md5sum 3546e1510c5b78fe76214f0c974dac46:
    /usr/lib/ocaml/3.06/camlp4/pa_extend_m.cmo
    /usr/lib/ocaml/3.06/camlp4/pa_extend.cmo

Actually, as you can see, we have inconsistencies :-(

Anyway, ... I'm in hurry now, you can think at them also on your own ;-P

Cheers.

-- 
Stefano Zacchiroli  -  Undergraduate Student of CS @ Uni. Bologna, Italy
zack@{cs.unibo.it,debian.org,bononia.it}  -  http://www.bononia.it/zack/
"  I know you believe you understood what you think I said, but I am not
sure you realize that what you heard is not what I meant!  " -- G.Romney
#!/usr/bin/ocamlrun /usr/bin/ocaml

(*
  Ocaml (is (not)) FUBAR - consistency checks over a set of OCaml
                           bytecode objects

  Copyright (C) <2003> Stefano Zacchiroli <zack@bononia.it>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*)

(*
  to check for consistency of your OCaml standard library directory:

    $ find `ocamlfind printconf stdlib` -name '*.cm[ao]' | o_fubar.ml -

  to check for consistency of a set of OCaml bytecode objects only:

    $ o_fubar.ml a.cmo b.cmo lib.cma ...
*)

#use "topfind";;
#require "pcre";;
#require "unix";;

open Printf;;

(* helpers *)

let rec fold_in f init ic =
  match (try Some (input_line ic) with End_of_file -> None) with
  | Some l -> fold_in f (f init l) ic
  | None -> init
;;
let input_lines ic = List.rev (fold_in (fun acc line -> line :: acc) [] ic) ;;
let read_lines cmd =
  let ic = Unix.open_process_in cmd in
  let lines = input_lines ic in
  close_in ic;
  lines
;;

(* constants *)

let usage_string =
"Usage:
  o_fubar.ml obj1 ...    [ bytecode objects list on cmd line     ]
  o_fubar.ml -           [ read bytecode objects list from stdin ]
" ;;
let iface_RE = Pcre.regexp "^\t[a-z0-9]{32}\t[A-Z]\\w*$" ;;
let tab_RE = Pcre.regexp "\t" ;;

(* data structures *)
  (* <interface_name, md5sum> -> files list *)
let files = Hashtbl.create 1024 ;;
  (* interface_name -> md5sum list *)
let md5sums = Hashtbl.create 128 ;;

(* let's go! *)

let objects = (* collect bytecode objects *)
  match List.tl (Array.to_list Sys.argv) with
  | [] ->
      prerr_endline "\nNo OCaml bytecode objects (*.cm[ao]) specified\n";
      prerr_endline usage_string;
      exit 1
  | "-"::_ -> input_lines stdin
  | objects -> objects
in
List.iter     (* fill tables *)
  (fun fname ->
    let ic = Unix.open_process_in ("objinfo " ^ fname) in
      (* (iface * md5sum) list *)
    let ifaces =
      fold_in
        (fun acc line ->
          if Pcre.pmatch ~rex:iface_RE line then
            match Pcre.split ~rex:tab_RE line with
            | [_; md5sum; iface] -> (iface, md5sum) :: acc
            | _ -> assert false
          else
            acc)
        []
        ic
    in
    close_in ic;
    List.iter
      (fun ((iface, md5sum) as assumption) ->
        if (not (Hashtbl.mem files assumption)) then
          Hashtbl.add files assumption [fname]
        else begin
          let prev = Hashtbl.find files assumption in
          if not (List.mem fname prev) then
            Hashtbl.replace files assumption (fname :: prev)
        end;
        if (not (Hashtbl.mem md5sums iface)) then
          Hashtbl.add md5sums iface [md5sum]
        else begin
          let prev = Hashtbl.find md5sums iface in
          if not (List.mem md5sum prev) then
            Hashtbl.replace md5sums iface (md5sum :: prev)
        end)
      ifaces)
  objects;
Hashtbl.iter  (* auditing: print incosistencies *)
  (fun iface md5sums ->
    let len = List.length md5sums in
    assert (len > 0);
    if len > 1 then begin
      printf "Inconsistent assumptions over %s:\n" iface;
      List.iter
        (fun md5sum ->
          printf "  Objects that believe %s has md5sum %s:\n" iface md5sum;
          List.iter
            (fun file -> printf "    %s\n" file)
            (Hashtbl.find files (iface, md5sum)))
        md5sums;
      flush stdout
   end)
  md5sums

Attachment: pgpegsTaTT0eS.pgp
Description: PGP signature


Reply to: