6 let gen dest_filename =
8 let basename = Filename.basename dest_filename in
9 let directory = Filename.dirname dest_filename in
10 let dirname = Filename.basename directory in
11 let up_directory = Filename.dirname directory in
12 let templates = Filename.concat up_directory "template" in
13 let template, keyword =
14 let keyword = ref "" in
15 let template = ref "" in
17 let len = String.length basename in
18 for i = 0 to len - 1 do
19 match basename.[i] with
21 template := "template" ^ (String.sub basename i (len-i));
22 keyword := String.sub basename 0 i;
23 !keyword.[0] <- Char.uppercase !keyword.[0];
28 with Exit -> !template, !keyword
32 prerr_endline (Printf.sprintf "FILE [%s]" dest_filename);
33 prerr_endline (Printf.sprintf "Replace [%s] by [%s]" "Template" keyword);
36 let ts = "Template" in
37 let ts_len = String.length ts in
39 let full_template = Filename.concat templates template in
40 let ic = open_in full_template in
41 let oc = open_out dest_filename in
44 let line = input_line ic in
46 let buf = Buffer.create 100 in
47 let len = String.length line in
48 (* Printf.printf "LINE [%d]" len; print_newline (); *)
51 (* Printf.printf "[%d]" i; print_newline (); *)
52 if i <= len - ts_len then
53 if line.[i] = 'T' && String.sub line i ts_len = ts then begin
54 Buffer.add_string buf keyword;
57 Buffer.add_char buf line.[i];
61 Buffer.add_string buf (String.sub line i (len-i))
64 output_string oc (Buffer.contents buf);
66 output_string oc line;
71 Printf.fprintf oc "(*\n\n WARNING: this file is automatically generated from: \n\t%s\n\n*)\n\n" full_template;
72 Printf.fprintf oc "# 1 \"%s\"\n" full_template;
79 let depend dest_filename =
80 if Sys.file_exists dest_filename then begin
81 let dest_filename = String.sub dest_filename 0 (String.length dest_filename - 1) in
82 let basename = Filename.basename dest_filename in
83 let directory = Filename.dirname dest_filename in
84 let dirname = Filename.basename directory in
85 let up_directory = Filename.dirname directory in
86 let templates = Filename.concat up_directory "template" in
87 let template, keyword =
88 let keyword = ref "" in
89 let template = ref "" in
91 let len = String.length basename in
92 for i = 0 to len - 1 do
93 match basename.[i] with
95 template := "template" ^ (String.sub basename i (len-i));
96 keyword := String.sub basename 0 i;
97 !keyword.[0] <- Char.uppercase !keyword.[0];
102 with Exit -> !template, !keyword
104 let full_template = Filename.concat templates template in
106 Printf.printf "%s: %s\n" dest_filename full_template
111 Include of string * (Str.regexp * string) list
112 | Line of int * string
113 | Regexps of (Str.regexp * string) list
122 regexps : (Str.regexp * string) list;
123 defines : string list;
127 let new_env = { regexps = []; defines = []; ifs = [] }
130 let lexer = make_lexer [
131 "include"; "where"; "and" ;
133 "ifdef"; "else"; "endif";
136 let rec parse_line = parser
137 [< 'Kwd "#"; key = parse_key >] -> key
139 and parse_key = parser
140 [< 'Kwd "include"; 'String filename; regexps = parse_where >] ->
141 Include (filename, regexps)
142 | [< 'Int line; 'String filename >] ->
143 Line (line, filename)
144 | [< 'Kwd "where"; 'String reg; 'Kwd "="; 'String templ;
145 regexps = parse_where >] ->
146 Regexps ( (Str.regexp reg, templ) :: regexps)
148 and parse_where = parser
149 [< 'Kwd "where"; 'String reg; 'Kwd "="; 'String templ;
150 regexps = parse_where >] ->
151 (Str.regexp reg, templ) :: regexps
152 | [< 'Kwd "and"; 'String reg; 'Kwd "="; 'String templ;
153 regexps = parse_where >] ->
154 (Str.regexp reg, templ) :: regexps
157 let rec preprocess filename env =
158 let ic = open_in filename in
160 let line_warning line =
161 Printf.fprintf !outch "(*\n\n WARNING: this file is automatically generated from: \n\t%s\n\n*)\n\n" filename;
162 Printf.fprintf !outch "# %d \"%s\"\n" (line+1) filename;
165 let rec iter_line i env =
166 let line = input_line ic in
168 let line = iter_regexps line env.regexps in
170 let len = String.length line in
172 if len > 1 && line.[0] = '#' then begin
174 let s = Stream.of_string line in
176 match parse_line (lexer s) with
177 Include (filename, regexps2) ->
179 { env with regexps = regexps2 @ env.regexps };
182 | Line (line, filename) ->
183 Printf.fprintf !outch "# %d \"%s\"\n" line filename;
185 | Regexps regexps2 ->
187 { env with regexps = regexps2 @ env.regexps }
190 Printf.fprintf stderr "Line [%s]:\n"
191 (String.escaped line);
192 Printf.fprintf stderr "Error %s in \"%s\" line %d (%d)\n"
193 (Printexc.to_string e) filename i (Stream.count s + 1);
197 output_string !outch line;
198 output_char !outch '\n';
204 and iter_regexps line regexps =
207 | (reg, templ) :: regexps ->
208 (* Printf.fprintf stderr "Checking replacement for %s\n" templ; *)
209 let line = Str.global_replace reg templ line in
210 iter_regexps line regexps
218 let pp filename = preprocess filename new_env
220 let add_depend filedep filename depends =
221 if not (List.mem filename !depends) then begin
222 Printf.fprintf !outch "%s: %s\n" filedep filename;
223 depends := filename :: !depends
226 let rec dep filedep filename env depends =
227 let ic = open_in filename in
229 let rec iter_line i env =
230 let line = input_line ic in
232 let line = iter_regexps line env.regexps in
234 let len = String.length line in
236 if len > 1 && line.[0] = '#' then begin
237 let s = Stream.of_string line in
239 match parse_line (lexer s) with
240 Include (filename, regexps2) ->
241 add_depend filedep filename depends;
243 { env with regexps = regexps2 @ env.regexps } depends;
245 | Line (line, filename) ->
246 add_depend filedep filename depends;
248 | Regexps regexps2 ->
249 { env with regexps = regexps2 @ env.regexps }
252 Printf.fprintf stderr "Line [%s]:\n"
253 (String.escaped line);
254 Printf.fprintf stderr "Error \"%s\" line %d (%d)\n"
255 filename i (Stream.count s + 1);
262 and iter_regexps line regexps =
265 | (reg, templ) :: regexps ->
266 let line = Str.global_replace reg templ line in
267 iter_regexps line regexps
270 ignore (iter_line 0 env)
274 let depend filename =
275 if Sys.file_exists filename then
276 if Filename.check_suffix filename ".mlt" then
277 let filedep = (Filename.chop_suffix filename ".mlt") ^ ".ml" in
278 dep filedep filename new_env (ref [])
280 Printf.fprintf stderr "Don't know what to do with %s\n" filename;
287 (* "-gen", Arg.String gen, " <filename> : generate filename"; *)
288 "-pp", Arg.String pp, " <filename> : preprocess filename";
289 "-o", Arg.String (fun s -> outch := open_out s), " <filename> : output filename (influences subsequent options)";