]> matita.cs.unibo.it Git - helm.git/blob - helm/matita/matitaMisc.ml
* Part of matita that used to deal with the library moved into ocaml/library
[helm.git] / helm / matita / matitaMisc.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 open MatitaTypes 
28
29 (** Functions "imported" from Http_getter_misc *)
30
31 let strip_trailing_slash = Http_getter_misc.strip_trailing_slash
32 let normalize_dir = Http_getter_misc.normalize_dir
33 let strip_suffix = Http_getter_misc.strip_suffix
34
35 let baseuri_of_baseuri_decl st =
36   match st with
37   | GrafiteAst.Executable (_, GrafiteAst.Command (_, GrafiteAst.Set (_, "baseuri", buri))) ->
38       Some buri
39   | _ -> None
40
41 let is_empty buri =
42  List.for_all
43   (function
44       Http_getter_types.Ls_section _ -> true
45     | Http_getter_types.Ls_object _ -> false)
46   (Http_getter.ls (Http_getter_misc.strip_trailing_slash buri ^ "/"))
47
48 let absolute_path file =
49   if file.[0] = '/' then file else Unix.getcwd () ^ "/" ^ file
50   
51 let is_proof_script fname = true  (** TODO Zack *)
52 let is_proof_object fname = true  (** TODO Zack *)
53
54 let append_phrase_sep s =
55   if not (Pcre.pmatch ~pat:(sprintf "%s$" BuildTimeConf.phrase_sep) s) then
56     s ^ BuildTimeConf.phrase_sep
57   else
58     s
59
60 exception History_failure
61
62 type 'a memento = 'a array * int * int * int  (* data, hd, tl, cur *)
63
64 class type ['a] history =
65   object
66     method add : 'a -> unit
67     method next : 'a
68     method previous : 'a
69     method load: 'a memento -> unit
70     method save: 'a memento
71     method is_begin: bool
72     method is_end: bool
73   end
74
75 class basic_history (head, tail, cur) =
76   object
77     val mutable hd = head  (* insertion point *)
78     val mutable tl = tail (* oldest inserted item *)
79     val mutable cur = cur  (* current item for the history *)
80     
81     method is_begin = cur <= tl
82     method is_end = cur >= hd
83   end
84   
85   
86 class shell_history size =
87   let size = size + 1 in
88   let decr x = let x' = x - 1 in if x' < 0 then size + x' else x' in
89   let incr x = (x + 1) mod size in
90   object (self)
91     val data = Array.create size ""
92
93     inherit basic_history (0, -1 , -1)
94     
95     method add s =
96       data.(hd) <- s;
97       if tl = -1 then tl <- hd;
98       hd <- incr hd;
99       if hd = tl then tl <- incr tl;
100       cur <- hd
101     method previous =
102       if cur = tl then raise History_failure;
103       cur <- decr cur;
104       data.(cur)
105     method next =
106       if cur = hd then raise History_failure;
107       cur <- incr cur;
108       if cur = hd then "" else data.(cur)
109     method load (data', hd', tl', cur') =
110       assert (Array.length data = Array.length data');
111       hd <- hd'; tl <- tl'; cur <- cur';
112       Array.blit data' 0 data 0 (Array.length data')
113     method save = (Array.copy data, hd, tl, cur)
114   end
115
116 class ['a] browser_history ?memento size init =
117   object (self)
118     initializer match memento with Some m -> self#load m | _ -> ()
119     val data = Array.create size init
120
121     inherit basic_history (0, 0, 0)
122     
123     method previous =
124       if cur = tl then raise History_failure;
125       cur <- cur - 1;
126       if cur = ~-1 then cur <- size - 1;
127       data.(cur)
128     method next =
129       if cur = hd then raise History_failure;
130       cur <- cur + 1;
131       if cur = size then cur <- 0;
132       data.(cur)
133     method add (e:'a) =
134       if e <> data.(cur) then
135         begin
136           cur <- cur + 1;
137           if cur = size then cur <- 0;
138           if cur = tl then tl <- tl + 1;
139           if tl = size then tl <- 0;
140           hd <- cur;
141           data.(cur) <- e
142         end
143     method load (data', hd', tl', cur') =
144       assert (Array.length data = Array.length data');
145       hd <- hd'; tl <- tl'; cur <- cur';
146       Array.blit data' 0 data 0 (Array.length data')
147     method save = (Array.copy data, hd, tl, cur)
148   end
149
150 let singleton f =
151   let instance = lazy (f ()) in
152   fun () -> Lazy.force instance
153
154 let image_path n = sprintf "%s/%s" BuildTimeConf.images_dir n
155
156 let end_ma_RE = Pcre.regexp "\\.ma$"
157
158 let list_tl_at ?(equality=(==)) e l =
159   let rec aux =
160     function
161     | [] -> raise Not_found
162     | hd :: tl as l when equality hd e -> l
163     | hd :: tl -> aux tl
164   in
165   aux l
166
167 let baseuri_of_file file = 
168   let uri = ref None in
169   let ic = open_in file in
170   let istream = Ulexing.from_utf8_channel ic in
171   (try
172     while true do
173       try 
174         let stm = GrafiteParser.parse_statement istream in
175         match baseuri_of_baseuri_decl stm with
176         | Some buri -> 
177             let u = strip_trailing_slash buri in
178             if String.length u < 5 || String.sub u 0 5 <> "cic:/" then
179               HLog.error (file ^ " sets an incorrect baseuri: " ^ buri);
180             (try 
181               ignore(Http_getter.resolve u)
182             with
183             | Http_getter_types.Unresolvable_URI _ -> 
184                 HLog.error (file ^ " sets an unresolvable baseuri: "^buri)
185             | Http_getter_types.Key_not_found _ -> ());
186             uri := Some u;
187             raise End_of_file
188         | None -> ()
189       with
190         CicNotationParser.Parse_error err ->
191           HLog.error ("Unable to parse: " ^ file);
192           HLog.error ("Parse error: " ^ err);
193           ()
194     done
195   with End_of_file -> close_in ic);
196   match !uri with
197   | Some uri -> uri
198   | None -> failwith ("No baseuri defined in " ^ file)
199
200 let obj_file_of_script ~basedir f =
201  if f = "coq.ma" then BuildTimeConf.coq_notation_script else
202   let baseuri = baseuri_of_file f in
203    LibraryMisc.obj_file_of_baseuri ~basedir ~baseuri
204