| 1 | (* |
| 2 | * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen |
| 3 | * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix |
| 4 | * This file is part of Coccinelle. |
| 5 | * |
| 6 | * Coccinelle is free software: you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation, according to version 2 of the License. |
| 9 | * |
| 10 | * Coccinelle is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>. |
| 17 | * |
| 18 | * The authors reserve the right to distribute this or future versions of |
| 19 | * Coccinelle under other licenses. |
| 20 | *) |
| 21 | |
| 22 | |
| 23 | (* split patch per file *) |
| 24 | |
| 25 | let is_diff = Str.regexp "diff " |
| 26 | let split_patch i = |
| 27 | let patches = ref [] in |
| 28 | let cur = ref [] in |
| 29 | let rec loop _ = |
| 30 | let l = input_line i in |
| 31 | (if Str.string_match is_diff l 0 |
| 32 | then |
| 33 | (if List.length !cur > 0 |
| 34 | then begin patches := List.rev !cur :: !patches; cur := [l] end) |
| 35 | else cur := l :: !cur); |
| 36 | loop() in |
| 37 | try loop() with End_of_file -> !patches |
| 38 | |
| 39 | (* ------------------------------------------------------------------------ *) |
| 40 | |
| 41 | (* can get_maintainers takea file as an argument, or only a patch? *) |
| 42 | let resolve_maintainers cmd patches = |
| 43 | let maintainer_table = Hashtbl.create (List.length patches) in |
| 44 | List.iter |
| 45 | (function |
| 46 | diff_line::rest -> |
| 47 | (match Str.split (Str.regexp " a/") diff_line with |
| 48 | [before;after] -> |
| 49 | (match Str.split (Str.regexp " ") after with |
| 50 | file::_ -> |
| 51 | (match Common.cmd_to_list (cmd ^ " " ^ file) with |
| 52 | [info] -> |
| 53 | let cell = |
| 54 | try Hashtbl.find maintainer_table info |
| 55 | with Not_found -> |
| 56 | let cell = ref [] in |
| 57 | Hashtbl.add maintainer_table info cell; |
| 58 | cell in |
| 59 | cell := (diff_line :: rest) :: !cell |
| 60 | | _ -> failwith "badly formatted maintainer result") |
| 61 | | _ -> failwith "filename not found") |
| 62 | | _ -> |
| 63 | failwith (Printf.sprintf "prefix a/ not found in %s" diff_line)) |
| 64 | | _ -> failwith "bad diff line") |
| 65 | patches; |
| 66 | maintainer_table |
| 67 | |
| 68 | (* ------------------------------------------------------------------------ *) |
| 69 | |
| 70 | let print_all o l = |
| 71 | List.iter (function x -> Printf.fprintf o "%s\n" x) l |
| 72 | |
| 73 | let make_output_files template maintainer_table patch = |
| 74 | let ctr = ref 0 in |
| 75 | Hashtbl.iter |
| 76 | (function maintainers -> |
| 77 | function diffs -> |
| 78 | ctr := !ctr + 1; |
| 79 | let o = open_out (Printf.sprintf "%s%d" patch !ctr) in |
| 80 | Printf.fprintf o "To: %s\n\n" maintainers; |
| 81 | print_all o template; |
| 82 | List.iter (print_all o) (List.rev !diffs); |
| 83 | close_out o) |
| 84 | maintainer_table |
| 85 | |
| 86 | (* ------------------------------------------------------------------------ *) |
| 87 | |
| 88 | let command = ref "get_maintainers.pl" |
| 89 | let file = ref "" |
| 90 | |
| 91 | let options = |
| 92 | ["-cmd", Arg.String (function x -> command := x), "get maintainer command"] |
| 93 | |
| 94 | let usage = "" |
| 95 | |
| 96 | let anonymous x = file := x |
| 97 | |
| 98 | let _ = |
| 99 | Arg.parse (Arg.align options) (fun x -> file := x) usage; |
| 100 | let i = open_in !file in |
| 101 | let patches = split_patch i in |
| 102 | let maintainer_table = resolve_maintainers !command patches in |
| 103 | let template = Common.cmd_to_list (Printf.sprintf "cat %s.tmp" !file) in |
| 104 | make_output_files template maintainer_table !file |