1
(***********************************************************************)
5
(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)
7
(* Copyright 2001 Institut National de Recherche en Informatique et *)
8
(* en Automatique. All rights reserved. This file is distributed *)
9
(* only by permission. *)
11
(***********************************************************************)
14
let l = in_channel_length ic in
15
let buf = String.create 1024 in
16
let res = Buffer.create l in
19
let n = input ic buf 0 1024 in
20
if n = 0 then raise Exit else
21
Buffer.add_substring res buf 0 n
24
with Exit -> Buffer.contents res;;
26
let string_of_file fname =
27
let ic = open_in fname in
28
let r = string_of_ic ic in
32
let copy_channel ic oc =
33
let buf = String.create 1024 in
36
let n = input ic buf 0 1024 in
37
if n = 0 then raise Exit else
42
let copy_file s copy =
44
let oc = open_out copy in
49
let bannerize_channel banner ic oc =
50
output_string oc banner;
53
let ckpname fname = fname ^ "~";;
55
let copy = ckpname fname in
59
let bannerize_file banner s =
60
let copy = ckp_file s in
61
let ic = open_in copy in
62
let oc = open_out s in
63
bannerize_channel banner ic oc;
67
let with_in_channel fname f =
68
let ic = open_in fname in
73
with x -> close_in ic; raise x;;
75
let with_out_channel fname f =
76
let oc = open_out fname in
81
with x -> close_out oc; raise x;;
83
let string_of_file fname = with_in_channel fname string_of_ic;;
85
let copy_file s copy =
86
with_in_channel s (fun ic -> with_out_channel copy (copy_channel ic));;
88
let bannerize_file banner fname =
89
let copy = ckp_file fname in
91
(fun ic -> with_out_channel fname (bannerize_channel banner ic));;
93
let skip_banner_channel banner_marker ic =
94
let l = try input_line ic with End_of_file -> "" in
95
if l = banner_marker then
97
while input_line ic <> banner_marker do () done
99
invalid_arg "replace_banner: end of banner not found"
102
(* The main function to rewrite files with banners. *)
103
let replace_banner banner_marker banner fname =
104
let copy = ckp_file fname in
107
skip_banner_channel banner_marker ic;
108
with_out_channel fname (bannerize_channel banner ic));;
110
(* To get the banner's marker. *)
111
let get_first_line fname = with_in_channel fname input_line;;
114
let files = ref [] in
115
let banner_file = ref "banner" in
116
let set_banner_file fname = banner_file := fname in
117
let record_file_name s = files := s :: !files in
118
let b_opt = Arg.String set_banner_file
120
" <banner file>: set the contents of file <banner file> as the banner \n\
121
(default name for the banner file is \"banner\")." in
123
["-b", b_opt, b_message;
124
"--banner", b_opt, b_message]
126
"Usage: banner [-b | --banner <banner file>] <files>\n\n\
127
This command adds a banner to the top of each file given in the list of\n\
129
The text of the banner is the contents of a <banner file> that can\n\
130
be fixed with the [-b] option (default banner file name is \"banner\").\n\
131
The text of a banner must be comprised between two identical lines,\n\
132
the ``banner markers'' (hence the first and the last lines of the\n\
133
banner file must be identical).\n\
134
Two banners are considered similar if they have the same banner markers.\n\
135
If a file already had a similar banner, this banner is removed \
137
the contents of the <banner file>. This way, slight modifications of the\n\
138
banner are easily handled.\n\n\
139
Prior to add a banner to the file \"f\", a checkpoint of \"f\" is\n\
140
written in the file named [f~].";
141
let banner_marker = get_first_line !banner_file in
142
let banner = string_of_file !banner_file in
143
List.iter (replace_banner banner_marker banner) !files;;
145
try main () with Sys_error s -> prerr_endline ("Fatal error: " ^ s); exit 1;;