Release coccinelle-0.2.3rc1
[bpt/coccinelle.git] / tools / gitsort.ml
CommitLineData
5636bb2c
C
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
9f8e26f4 23(*
ae4735db 24 * Copyright 2005-2010, Ecole des Mines de Nantes, University of Copenhagen
9f8e26f4
C
25 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
26 * This file is part of Coccinelle.
27 *
28 * Coccinelle is free software: you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation, according to version 2 of the License.
31 *
32 * Coccinelle is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
39 *
40 * The authors reserve the right to distribute this or future versions of
41 * Coccinelle under other licenses.
42 *)
43
44
34e49164
C
45(* sort a list of git codes such that the most recent comes first *)
46
47let git_home = ref "/home/julia/linux-2.6"
48
49let unwind_protect f cleanup =
50 try f ()
51 with e -> begin cleanup e; raise e end
52
53let (with_open_infile: string -> ((in_channel) -> 'a) -> 'a) = fun file f ->
54 let chan = open_in file in
ae4735db 55 unwind_protect (fun () ->
34e49164
C
56 let res = f chan in
57 close_in chan;
58 res)
59 (fun e -> close_in chan)
60
61(* ----------------------------------------------------------------------- *)
62
63let months =
64 [("Jan",1);("Feb",2);("Mar",3);("Apr",4);("May",5);("Jun",6);("Jul",7);
65 ("Aug",8);("Sep",9);("Oct",10);("Nov",11);("Dec",12)]
66
67let antimonths =
68 [(1,31);(2,28);(3,31);(4,30);(5,31); (6,30);(7,31);(8,31);(9,30);(10,31);
69 (11,30);(12,31);(0,31)]
70
71let normalize (year,month,day,hour,minute,second) =
72 if hour < 0
73 then
74 let (day,hour) = (day - 1,hour + 24) in
75 if day = 0
76 then
77 let month = month - 1 in
78 let day = List.assoc month antimonths in
79 let day =
80 if month = 2 && year / 4 * 4 = year && not (year / 100 * 100 = year)
81 then 29
82 else day in
83 if month = 0
84 then (year-1,12,day,hour,minute,second)
85 else (year,month,day,hour,minute,second)
86 else (year,month,day,hour,minute,second)
87 else (year,month,day,hour,minute,second)
88
89exception Fail of string
90
91let read_info code =
92 let _ =
93 Sys.command
94 (Printf.sprintf
95 "pushd %s >& /dev/null ; git log %s^..%s | grep Date: > /tmp/gitsort_info ; popd >& /dev/null"
96 !git_home code code) in
97 with_open_infile "/tmp/gitsort_info" (fun i ->
98 let l =
99 try input_line i
100 with End_of_file -> raise (Fail "bad git file") in
101 match Str.split (Str.regexp " ") l with
102 [date;_;_;weekday;month;day;time;year;offset] ->
103 let day = int_of_string day in
104 let month = List.assoc month months in
105 let year = int_of_string year in
106 (match Str.split (Str.regexp ":") time with
107 [hour;minute;second] ->
108 let hour = int_of_string hour in
109 let minute = int_of_string minute in
110 let second = int_of_string second in
111 let modifier =
112 match String.get offset 0 with
113 '-' -> -1
114 | '+' -> 1
115 | _ -> raise (Fail "bad offset") in
116 (if not (String.sub offset 3 2 = "00")
117 then raise (Fail "require 0 minutes difference"));
118 let hour =
119 hour + (modifier * (int_of_string (String.sub offset 1 2))) in
120 normalize (year,month,day,hour,minute,second)
121 | _ -> raise (Fail "bad date2"))
122 | l -> raise (Fail ("bad date1: "^(String.concat "|" l))))
123
124let rec get_dates = function
125 [] -> []
126 | code::rest ->
127 let date =
128 try Some (read_info code)
129 with
130 Fail s -> Printf.printf "problem in %s: %s\n" code s; None
131 | _ -> Printf.printf "problem in %s\n" code; None in
132 match date with
133 Some date -> (date,code)::(get_dates rest)
134 | None -> get_dates rest
135
136let get_codes file =
137 let gits = ref ([] : string list) in
138 with_open_infile file (fun i ->
139 let rec loop _ =
140 let git = try Some (input_line i) with End_of_file -> None in
141 match git with
142 Some x -> gits := x :: !gits; loop()
143 | None -> () in
144 loop ());
145 List.concat
146 (List.map
147 (function l ->
148 List.filter
149 (* all because I don't know how to make a backslash regexp...*)
150 (function x -> String.length x > 10)
151 (Str.split (Str.regexp "[ \t]+") l))
152 !gits)
153
154let _ =
155 let args = Array.to_list Sys.argv in
156 let file =
157 match args with
158 [_;git_home_info;gits] -> git_home := git_home_info; gits
159 | [_;gits] -> gits
160 | _ -> failwith "args: [git home] git_codes_file" in
161 let codes = get_codes file in
162 let dates = get_dates codes in
163 match List.sort compare dates with
164 (_,last)::prev ->
165 List.iter (function (_,x) -> Printf.printf "%s \\\n" x) (List.rev prev);
166 Printf.printf "%s\n" last
167 | _ -> ()
168
ae4735db
C
169
170