]> matita.cs.unibo.it Git - helm.git/blob - helm/matita/matitacLib.ml
07d58b3955201e5e1de8836b5a4fa7cd01cc748e
[helm.git] / helm / matita / matitacLib.ml
1 (* Copyright (C) 2004-2005, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://helm.cs.unibo.it/
24  *)
25
26 open Printf
27
28 open GrafiteTypes
29
30 let pp_ast_statement =
31   GrafiteAstPp.pp_statement ~term_pp:CicNotationPp.pp_term
32     ~lazy_term_pp:CicNotationPp.pp_term ~obj_pp:CicNotationPp.pp_obj
33
34 (** {2 Initialization} *)
35
36 let status = ref None
37
38 let run_script is eval_function  =
39   let status = 
40     match !status with
41     | None -> assert false
42     | Some s -> s
43   in
44   let slash_n_RE = Pcre.regexp "\\n" in
45   let cb = 
46     if Helm_registry.get_bool "matita.quiet" then 
47       (fun _ _ -> ())
48     else 
49       (fun status stm ->
50         (* dump_status status; *)
51         let stm = pp_ast_statement stm in
52         let stm = Pcre.replace ~rex:slash_n_RE stm in
53         let stm =
54           if String.length stm > 50 then
55             String.sub stm 0 50 ^ " ..."
56           else
57             stm
58         in
59         HLog.debug ("Executing: ``" ^ stm ^ "''"))
60   in
61   try
62     eval_function status is cb
63   with
64   | GrafiteEngine.Drop  
65   | End_of_file
66   | CicNotationParser.Parse_error _ as exn -> raise exn
67   | exn -> 
68       HLog.error (snd (MatitaExcPp.to_string exn));
69       raise exn
70
71 let fname () =
72   match Helm_registry.get_list Helm_registry.string "matita.args" with
73   | [x] -> x
74   | _ -> MatitaInit.die_usage ()
75
76 let pp_ocaml_mode () = 
77   HLog.message "";
78   HLog.message "                      ** Entering Ocaml mode ** ";
79   HLog.message "";
80   HLog.message "Type 'go ();;' to enter an interactive matitac";
81   HLog.message ""
82   
83 let clean_exit n =
84  let opt_exit =
85   function
86      None -> ()
87    | Some n -> exit n
88  in
89   match !status with
90      None -> opt_exit n
91    | Some status ->
92       try
93        let baseuri = GrafiteTypes.get_string_option !status "baseuri" in
94        let basedir = Helm_registry.get "matita.basedir" in
95        LibraryClean.clean_baseuris ~basedir ~verbose:false [baseuri];
96        opt_exit n
97       with GrafiteTypes.Option_error("baseuri", "not found") ->
98        (* no baseuri ==> nothing to clean yet *)
99        opt_exit n
100   
101 let rec interactive_loop () = 
102   let str = Ulexing.from_utf8_channel stdin in
103   try
104     run_script str 
105       (MatitaEngine.eval_from_stream ~prompt:true
106       ~include_paths:(Helm_registry.get_list Helm_registry.string
107         "matita.includes"))
108   with 
109   | GrafiteEngine.Drop -> pp_ocaml_mode ()
110   | Sys.Break -> HLog.error "user break!"; interactive_loop ()
111   | GrafiteTypes.Command_error _ -> interactive_loop ()
112   | End_of_file ->
113      print_newline ();
114      clean_exit (Some 0)
115   | HExtlib.Localized (floc,CicNotationParser.Parse_error err) ->
116      let (x, y) = HExtlib.loc_of_floc floc in
117      HLog.error (sprintf "Parse error at %d-%d: %s" x y err);
118      interactive_loop ()
119   | exn -> HLog.error (Printexc.to_string exn); interactive_loop ()
120
121 let go () =
122   Helm_registry.load_from BuildTimeConf.matita_conf;
123   CicNotation2.load_notation BuildTimeConf.core_notation_script;
124   Http_getter.init ();
125   MetadataTypes.ownerize_tables (Helm_registry.get "matita.owner");
126   LibraryDb.create_owner_environment ();
127   CicEnvironment.set_trust (* environment trust *)
128     (let trust = Helm_registry.get_bool "matita.environment_trust" in
129      fun _ -> trust);
130   status := Some (ref (MatitaSync.init ()));
131   Sys.catch_break true;
132   interactive_loop ()
133
134 let main ~mode = 
135   MatitaInit.initialize_all ();
136   (* must be called after init since args are set by cmdline parsing *)
137   let fname = fname () in
138   status := Some (ref (MatitaSync.init ()));
139   Sys.catch_break true;
140   let origcb = HLog.get_log_callback () in
141   let newcb tag s =
142     match tag with
143     | `Debug | `Message -> ()
144     | `Warning | `Error -> origcb tag s
145   in
146   if Helm_registry.get_bool "matita.quiet" then
147     HLog.set_log_callback newcb;
148   let matita_debug = Helm_registry.get_bool "matita.debug" in
149   try
150     let time = Unix.time () in
151     if Helm_registry.get_bool "matita.quiet" then
152       origcb `Message ("compiling " ^ Filename.basename fname ^ "...")
153     else
154       HLog.message (sprintf "execution of %s started:" fname);
155     let is =
156       Ulexing.from_utf8_channel
157         (match fname with
158         | "stdin" -> stdin
159         | fname -> open_in fname) in
160     let include_paths =
161      Helm_registry.get_list Helm_registry.string "matita.includes" in
162     (try
163       run_script is 
164        (MatitaEngine.eval_from_stream ~include_paths
165          ~clean_baseuri:(not (Helm_registry.get_bool "matita.preserve")))
166      with End_of_file -> ());
167     let elapsed = Unix.time () -. time in
168     let tm = Unix.gmtime elapsed in
169     let sec = 
170       if tm.Unix.tm_sec > 0 then (string_of_int tm.Unix.tm_sec ^ "''") else "" 
171     in
172     let min = 
173       if tm.Unix.tm_min > 0 then (string_of_int tm.Unix.tm_min ^ "' ") else "" 
174     in
175     let hou = 
176       if tm.Unix.tm_hour > 0 then (string_of_int tm.Unix.tm_hour ^ "h ") else ""
177     in
178     let proof_status,moo_content_rev,metadata,status = 
179       match !status with
180       | Some s -> !s.proof_status, !s.moo_content_rev, !s.metadata, !s
181       | None -> assert false
182     in
183     if proof_status <> GrafiteTypes.No_proof then
184      begin
185       HLog.error
186        "there are still incomplete proofs at the end of the script";
187       clean_exit (Some 2)
188      end
189     else
190      begin
191        let basedir = Helm_registry.get "matita.basedir" in
192        let baseuri = GrafiteParserMisc.baseuri_of_script ~include_paths fname in
193        let moo_fname = LibraryMisc.obj_file_of_baseuri ~basedir ~baseuri in
194        let metadata_fname = LibraryMisc.metadata_file_of_baseuri ~basedir ~baseuri in
195        GrafiteMarshal.save_moo moo_fname moo_content_rev;
196        LibraryNoDb.save_metadata metadata_fname metadata;
197        HLog.message 
198          (sprintf "execution of %s completed in %s." fname (hou^min^sec));
199        exit 0
200      end
201   with 
202   | Sys.Break ->
203       HLog.error "user break!";
204       if mode = `COMPILER then
205         clean_exit (Some ~-1)
206       else
207         pp_ocaml_mode ()
208   | GrafiteEngine.Drop ->
209       if mode = `COMPILER then 
210         clean_exit (Some 1)
211       else 
212         pp_ocaml_mode ()
213   | HExtlib.Localized (floc,CicNotationParser.Parse_error err) ->
214      let (x, y) = HExtlib.loc_of_floc floc in
215      HLog.error (sprintf "Parse error at %d-%d: %s" x y err);
216      if mode = `COMPILER then
217        clean_exit (Some 1)
218      else
219        pp_ocaml_mode ()
220   | exn ->
221       if matita_debug then raise exn;
222       if mode = `COMPILER then 
223         clean_exit (Some 3)
224       else 
225         pp_ocaml_mode ()
226