(* * Copyright 2012, INRIA * Julia Lawall, Gilles Muller * Copyright 2010-2011, INRIA, University of Copenhagen * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix * This file is part of Coccinelle. * * Coccinelle 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, according to version 2 of the License. * * Coccinelle 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 Coccinelle. If not, see . * * The authors reserve the right to distribute this or future versions of * Coccinelle under other licenses. *) (* sort a list of git codes such that the most recent comes first *) let git_home = ref "/home/julia/linux-2.6" let unwind_protect f cleanup = try f () with e -> begin cleanup e; raise e end let (with_open_infile: string -> ((in_channel) -> 'a) -> 'a) = fun file f -> let chan = open_in file in unwind_protect (fun () -> let res = f chan in close_in chan; res) (fun e -> close_in chan) (* ----------------------------------------------------------------------- *) let months = [("Jan",1);("Feb",2);("Mar",3);("Apr",4);("May",5);("Jun",6);("Jul",7); ("Aug",8);("Sep",9);("Oct",10);("Nov",11);("Dec",12)] let antimonths = [(1,31);(2,28);(3,31);(4,30);(5,31); (6,30);(7,31);(8,31);(9,30);(10,31); (11,30);(12,31);(0,31)] let normalize (year,month,day,hour,minute,second) = if hour < 0 then let (day,hour) = (day - 1,hour + 24) in if day = 0 then let month = month - 1 in let day = List.assoc month antimonths in let day = if month = 2 && year / 4 * 4 = year && not (year / 100 * 100 = year) then 29 else day in if month = 0 then (year-1,12,day,hour,minute,second) else (year,month,day,hour,minute,second) else (year,month,day,hour,minute,second) else (year,month,day,hour,minute,second) exception Fail of string let read_info code = let _ = Sys.command (Printf.sprintf "pushd %s >& /dev/null ; git log %s^..%s | grep Date: > /tmp/gitsort_info ; popd >& /dev/null" !git_home code code) in with_open_infile "/tmp/gitsort_info" (fun i -> let l = try input_line i with End_of_file -> raise (Fail "bad git file") in match Str.split (Str.regexp " ") l with [date;_;_;weekday;month;day;time;year;offset] -> let day = int_of_string day in let month = List.assoc month months in let year = int_of_string year in (match Str.split (Str.regexp ":") time with [hour;minute;second] -> let hour = int_of_string hour in let minute = int_of_string minute in let second = int_of_string second in let modifier = match String.get offset 0 with '-' -> -1 | '+' -> 1 | _ -> raise (Fail "bad offset") in (if not (String.sub offset 3 2 = "00") then raise (Fail "require 0 minutes difference")); let hour = hour + (modifier * (int_of_string (String.sub offset 1 2))) in normalize (year,month,day,hour,minute,second) | _ -> raise (Fail "bad date2")) | l -> raise (Fail ("bad date1: "^(String.concat "|" l)))) let rec get_dates = function [] -> [] | code::rest -> let date = try Some (read_info code) with Fail s -> Printf.printf "problem in %s: %s\n" code s; None | _ -> Printf.printf "problem in %s\n" code; None in match date with Some date -> (date,code)::(get_dates rest) | None -> get_dates rest let get_codes file = let gits = ref ([] : string list) in with_open_infile file (fun i -> let rec loop _ = let git = try Some (input_line i) with End_of_file -> None in match git with Some x -> gits := x :: !gits; loop() | None -> () in loop ()); List.concat (List.map (function l -> List.filter (* all because I don't know how to make a backslash regexp...*) (function x -> String.length x > 10) (Str.split (Str.regexp "[ \t]+") l)) !gits) let _ = let args = Array.to_list Sys.argv in let file = match args with [_;git_home_info;gits] -> git_home := git_home_info; gits | [_;gits] -> gits | _ -> failwith "args: [git home] git_codes_file" in let codes = get_codes file in let dates = get_dates codes in match List.sort compare dates with (_,last)::prev -> List.iter (function (_,x) -> Printf.printf "%s \\\n" x) (List.rev prev); Printf.printf "%s\n" last | _ -> ()