1 (**************************************************************************)
2 (* *)
3 (* OCaml *)
4 (* *)
5 (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
6 (* *)
7 (* Copyright 1996 Institut National de Recherche en Informatique et *)
8 (* en Automatique. *)
9 (* *)
10 (* All rights reserved. This file is distributed under the terms of *)
11 (* the GNU Lesser General Public License version 2.1, with the *)
12 (* special exception on linking described in the file LICENSE. *)
13 (* *)
14 (**************************************************************************)
15
16 (* "Expunge" a toplevel by removing compiler modules from the global map.
17 Usage: expunge <source file> <dest file> <names of modules to keep> *)
18
19 open Misc
20 module String = Misc.Stdlib.String
21
22 let is_exn =
23 let h = Hashtbl.create 64 in
24 Array.iter (fun n -> Hashtbl.add h n ()) Runtimedef.builtin_exceptions;
25 Hashtbl.mem h
26
27 let to_keep = ref String.Set.empty
28
29 let negate = Sys.argv.(3) = "-v"
30
31 let keep =
32 if negate then fun name -> is_exn name || not (String.Set.mem name !to_keep)
33 else fun name -> is_exn name || (String.Set.mem name !to_keep)
34
35 let expunge_map tbl =
36 Symtable.filter_global_map (fun id -> keep (Ident.name id)) tbl
37
38 let expunge_crcs tbl =
39 List.filter (fun (unit, _crc) -> keep unit) tbl
40
41 let main () =
42 let input_name = Sys.argv.(1) in
43 let output_name = Sys.argv.(2) in
44 for i = (if negate then 4 else 3) to Array.length Sys.argv - 1 do
45 to_keep := String.Set.add (String.capitalize_ascii Sys.argv.(i)) !to_keep
46 done;
47 let ic = open_in_bin input_name in
48 Bytesections.read_toc ic;
49 let toc = Bytesections.toc() in
50 let pos_first_section = Bytesections.pos_first_section ic in
51 let oc =
52 open_out_gen [Open_wronly; Open_creat; Open_trunc; Open_binary] 0o777
53 output_name in
54 (* Copy the file up to the symbol section as is *)
55 seek_in ic 0;
56 copy_file_chunk ic oc pos_first_section;
57 (* Copy each section, modifying the symbol section in passing *)
58 Bytesections.init_record oc;
59 List.iter
60 (fun (name, len) ->
61 begin match name with
62 "SYMB" ->
63 let global_map = (input_value ic : Symtable.global_map) in
64 output_value oc (expunge_map global_map)
65 | "CRCS" ->
66 let crcs = (input_value ic : (string * Digest.t option) list) in
67 output_value oc (expunge_crcs crcs)
68 | _ ->
69 copy_file_chunk ic oc len
70 end;
71 Bytesections.record oc name)
72 toc;
73 (* Rewrite the toc and trailer *)
74 Bytesections.write_toc_and_trailer oc;
75 (* Done *)
76 close_in ic;
77 close_out oc
78
79 let _ = Printexc.catch main (); exit 0
80