1 (***********************************************************************)
5 (* Luc Maranget, projet Moscova, *)
6 (* INRIA Rocquencourt *)
8 (* Copyright 2002 Institut National de Recherche en Informatique et *)
9 (* en Automatique. All rights reserved. This file is distributed *)
10 (* under the terms of the Q Public License version 1.0. *)
12 (***********************************************************************)
19 (* To copy the ML code fragments *)
25 mutable cur_line : int;
28 let open_tracker file oc = {
31 ic = open_in_bin file;
35 let close_tracker tr = close_in_noerr tr.ic;;
37 let update_tracker tr =
40 let cr_seen = ref false in
42 match input_char tr.ic with
43 | '\010' when not !cr_seen -> tr.cur_line <- tr.cur_line + 1;
44 | '\013' -> cr_seen := true; tr.cur_line <- tr.cur_line + 1;
45 | _ -> cr_seen := false;
46 done with End_of_file ->
47 fprintf tr.oc "# %d \"%s\"\n" (tr.cur_line+1) tr.file;
50 let copy_buffer = String.create 1024
52 let copy_chars_unix ic oc start stop =
53 let n = ref (stop - start) in
55 let m = input ic copy_buffer 0 (min !n 1024) in
56 output oc copy_buffer 0 m;
60 let copy_chars_win32 ic oc start stop =
61 for i = start to stop - 1 do
62 let c = input_char ic in
63 if c <> '\r' then output_char oc c
67 match Sys.os_type with
68 "Win32" | "Cygwin" -> copy_chars_win32
69 | _ -> copy_chars_unix
71 let copy_chunk sourcefile ic oc trl loc add_parens =
72 if loc.start_pos < loc.end_pos || add_parens then begin
73 fprintf oc "# %d \"%s\"\n" loc.start_line sourcefile;
74 if add_parens then begin
75 for i = 1 to loc.start_col - 1 do output_char oc ' ' done;
78 for i = 1 to loc.start_col do output_char oc ' ' done;
80 seek_in ic loc.start_pos;
81 copy_chars ic oc loc.start_pos loc.end_pos;
82 if add_parens then output_char oc ')';
86 (* Various memory actions *)
88 let output_mem_access oc i = fprintf oc "lexbuf.Lexing.lex_mem.(%d)" i
90 let output_memory_actions pref oc = function
93 output_string oc "(* " ;
94 fprintf oc "L=%d " (List.length mvs) ;
96 (fun mv -> match mv with
98 fprintf oc "[%d] <- [%d] ;" tgt src
100 fprintf oc "[%d] <- p ; " tgt)
102 output_string oc " *)\n" ;
104 (fun mv -> match mv with
108 pref output_mem_access tgt output_mem_access src
110 fprintf oc "%s%a <- lexbuf.Lexing.lex_curr_pos ;\n"
111 pref output_mem_access tgt)
114 let output_base_mem oc = function
115 | Mem i -> output_mem_access oc i
116 | Start -> fprintf oc "lexbuf.Lexing.lex_start_pos"
117 | End -> fprintf oc "lexbuf.Lexing.lex_curr_pos"
119 let output_tag_access oc = function
123 fprintf oc "(%a + %d)" output_base_mem a i
125 let output_env sourcefile ic oc tr env =
126 let pref = ref "let" in
130 (* Probably, we are better with variables sorted
131 in apparition order *)
134 (fun ((_,p1),_) ((_,p2),_) ->
135 Pervasives.compare p1.start_pos p2.start_pos)
140 fprintf oc "%s\n" !pref ;
141 copy_chunk sourcefile ic oc tr pos false ;
143 | Ident_string (o,nstart,nend) ->
145 "= Lexing.sub_lexeme%s lexbuf %a %a"
146 (if o then "_opt" else "")
147 output_tag_access nstart output_tag_access nend
148 | Ident_char (o,nstart) ->
150 "= Lexing.sub_lexeme_char%s lexbuf %a"
151 (if o then "_opt" else "")
152 output_tag_access nstart
158 (* Output the user arguments *)
159 let output_args oc args =
160 List.iter (fun x -> (output_string oc x; output_char oc ' ')) args
163 let quiet_mode = ref false;;