summaryrefslogtreecommitdiff
path: root/tools/read_cmt.ml
blob: c0c5eb09dcdbab0d212d61cec7059f346caee008 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(***********************************************************************)
(*                                                                     *)
(*                                OCaml                                *)
(*                                                                     *)
(*                  Fabrice Le Fessant, INRIA Saclay                   *)
(*                                                                     *)
(*  Copyright 2012 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  under the terms of the Q Public License version 1.0.               *)
(*                                                                     *)
(***********************************************************************)

let gen_annot = ref false
let gen_ml = ref false
let print_info_arg = ref false
let target_filename = ref None

let arg_list = [
  "-o", Arg.String (fun s ->
    target_filename := Some s
  ), " FILE (or -) : dump to file FILE (or stdout)";
  "-annot", Arg.Set gen_annot, " : generate the corresponding .annot file";
  "-src", Arg.Set gen_ml, " : generate an equivalent of the original source file (without comments) from a .cmt or a .cmti file";
  "-info", Arg.Set print_info_arg, " : print information on the file";
  ]

let arg_usage = "read_cmt [OPTIONS] FILE.cmt : read FILE.cmt and print related information"

let print_info cmt =
  let open Cmt_format in
      Printf.printf "module name: %s\n" cmt.cmt_modname;
      begin match cmt.cmt_annots with
          Packed (_, list) -> Printf.printf "pack: %s\n" (String.concat " " list)
        | Implementation _ -> Printf.printf "kind: implementation\n"
        | Interface _ -> Printf.printf "kind: interface\n"
        | Partial_implementation _ -> Printf.printf "kind: implementation with errors\n"
        | Partial_interface _ -> Printf.printf "kind: interface with errors\n"
      end;
      Printf.printf "command: %s\n" (String.concat " " (Array.to_list cmt.cmt_args));
      begin match cmt.cmt_sourcefile with
          None -> ()
        | Some name ->
          Printf.printf "sourcefile: %s\n" name;
      end;
      Printf.printf "build directory: %s\n" cmt.cmt_builddir;
      List.iter (fun dir -> Printf.printf "load path: %s\n%!" dir) cmt.cmt_loadpath;
      begin
      match cmt.cmt_source_digest with
          None -> ()
        | Some digest -> Printf.printf "source digest: %s\n" (Digest.to_hex digest);
      end;
      begin
      match cmt.cmt_interface_digest with
          None -> ()
        | Some digest -> Printf.printf "interface digest: %s\n" (Digest.to_hex digest);
      end;
      List.iter (fun (name, digest) ->
        Printf.printf "import: %s %s\n" name (Digest.to_hex digest);
      ) (List.sort compare cmt.cmt_imports);
      Printf.printf "%!";
      ()

let _ =
  Clflags.annotations := true;

  Arg.parse arg_list  (fun filename ->
    if
      Filename.check_suffix filename ".cmt" ||
        Filename.check_suffix filename ".cmti"
    then begin
      (*      init_path(); *)
      let cmt = Cmt_format.read_cmt filename in
      if !gen_annot then Cmt2annot.gen_annot !target_filename filename cmt;
      if !gen_ml then Cmt2annot.gen_ml !target_filename filename cmt;
      if !print_info_arg || not (!gen_ml || !gen_annot) then print_info cmt;
    end else begin
      Printf.fprintf stderr "Error: the file must have an extension in .cmt or .cmti.\n%!";
      Arg.usage arg_list arg_usage
    end
  ) arg_usage