aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/coqProject_file.ml42
-rw-r--r--lib/envars.ml1
-rw-r--r--lib/loc.ml2
-rw-r--r--lib/loc.mli5
-rw-r--r--lib/system.ml2
-rw-r--r--lib/unicode.ml43
-rw-r--r--lib/unicode.mli3
-rw-r--r--lib/util.ml9
-rw-r--r--lib/util.mli5
9 files changed, 63 insertions, 9 deletions
diff --git a/lib/coqProject_file.ml4 b/lib/coqProject_file.ml4
index 13de731f5..970666638 100644
--- a/lib/coqProject_file.ml4
+++ b/lib/coqProject_file.ml4
@@ -206,7 +206,7 @@ let rec find_project_file ~from ~projfile_name =
if Sys.file_exists fname then Some fname
else
let newdir = Filename.dirname from in
- if newdir = "" || newdir = "/" then None
+ if newdir = from then None
else find_project_file ~from:newdir ~projfile_name
;;
diff --git a/lib/envars.ml b/lib/envars.ml
index 68604ae6c..206d75033 100644
--- a/lib/envars.ml
+++ b/lib/envars.ml
@@ -213,6 +213,7 @@ let print_config ?(prefix_var_name="") f coq_src_subdirs =
fprintf f "%sCAMLP4BIN=%s/\n" prefix_var_name (camlp4bin ());
fprintf f "%sCAMLP4LIB=%s\n" prefix_var_name (camlp4lib ());
fprintf f "%sCAMLP4OPTIONS=%s\n" prefix_var_name Coq_config.camlp4compat;
+ fprintf f "%sCAMLFLAGS=%s\n" prefix_var_name Coq_config.caml_flags;
fprintf f "%sHASNATDYNLINK=%s\n" prefix_var_name
(if Coq_config.has_natdynlink then "true" else "false");
fprintf f "%sCOQ_SRC_SUBDIRS=%s\n" prefix_var_name (String.concat " " coq_src_subdirs)
diff --git a/lib/loc.ml b/lib/loc.ml
index 06da13d44..4a935a9d9 100644
--- a/lib/loc.ml
+++ b/lib/loc.ml
@@ -62,6 +62,8 @@ let merge_opt l1 l2 = match l1, l2 with
let unloc loc = (loc.bp, loc.ep)
+let shift_loc kb kp loc = { loc with bp = loc.bp + kb ; ep = loc.ep + kp }
+
(** Located type *)
type 'a located = t option * 'a
diff --git a/lib/loc.mli b/lib/loc.mli
index d4061e044..fde490cc8 100644
--- a/lib/loc.mli
+++ b/lib/loc.mli
@@ -40,6 +40,11 @@ val merge : t -> t -> t
val merge_opt : t option -> t option -> t option
(** Merge locations, usually generating the largest possible span *)
+val shift_loc : int -> int -> t -> t
+(** [shift_loc loc n p] shifts the beginning of location by [n] and
+ the end by [p]; it is assumed that the shifts do not change the
+ lines at which the location starts and ends *)
+
(** {5 Located exceptions} *)
val add_loc : Exninfo.info -> t -> Exninfo.info
diff --git a/lib/system.ml b/lib/system.ml
index 12eacf2ea..0b64b237d 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -52,7 +52,7 @@ let dirmap = ref StrMap.empty
let make_dir_table dir =
let filter_dotfiles s f = if f.[0] = '.' then s else StrSet.add f s in
- Array.fold_left filter_dotfiles StrSet.empty (readdir dir)
+ Array.fold_left filter_dotfiles StrSet.empty (Sys.readdir dir)
let exists_in_dir_respecting_case dir bf =
let cache_dir dir =
diff --git a/lib/unicode.ml b/lib/unicode.ml
index 959ccaf73..8eb2eb45d 100644
--- a/lib/unicode.ml
+++ b/lib/unicode.ml
@@ -163,6 +163,39 @@ let is_utf8 s =
in
try check 0 with End_of_input -> true | Invalid_argument _ -> false
+(* Escape string if it contains non-utf8 characters *)
+
+let escaped_non_utf8 s =
+ let mk_escape x = Printf.sprintf "%%%X" x in
+ let buff = Buffer.create (String.length s * 3) in
+ let rec process_trailing_aux i j =
+ if i = j then i else
+ match String.unsafe_get s i with
+ | '\128'..'\191' -> process_trailing_aux (i+1) j
+ | _ -> i in
+ let process_trailing i n =
+ let j = if i+n-1 >= String.length s then i+1 else process_trailing_aux (i+1) (i+n) in
+ (if j = i+n then
+ Buffer.add_string buff (String.sub s i n)
+ else
+ let v = Array.init (j-i) (fun k -> mk_escape (Char.code s.[i+k])) in
+ Buffer.add_string buff (String.concat "" (Array.to_list v)));
+ j in
+ let rec process i =
+ if i >= String.length s then Buffer.contents buff else
+ let c = String.unsafe_get s i in
+ match c with
+ | '\000'..'\127' -> Buffer.add_char buff c; process (i+1)
+ | '\128'..'\191' | '\248'..'\255' -> Buffer.add_string buff (mk_escape (Char.code c)); process (i+1)
+ | '\192'..'\223' -> process (process_trailing i 2)
+ | '\224'..'\239' -> process (process_trailing i 3)
+ | '\240'..'\247' -> process (process_trailing i 4)
+ in
+ process 0
+
+let escaped_if_non_utf8 s =
+ if is_utf8 s then s else escaped_non_utf8 s
+
(* Check the well-formedness of an identifier *)
let initial_refutation j n s =
@@ -198,7 +231,7 @@ let ident_refutation s =
|x -> x
with
| End_of_input -> Some (true,"The empty string is not an identifier.")
- | Invalid_argument _ -> Some (true,s^": invalid utf8 sequence.")
+ | Invalid_argument _ -> Some (true,escaped_non_utf8 s^": invalid utf8 sequence.")
let lowercase_unicode =
let tree = Segmenttree.make Unicodetable.to_lower in
@@ -268,9 +301,7 @@ let utf8_length s =
| '\192'..'\223' -> nc := 1 (* expect 1 continuation byte *)
| '\224'..'\239' -> nc := 2 (* expect 2 continuation bytes *)
| '\240'..'\247' -> nc := 3 (* expect 3 continuation bytes *)
- | '\248'..'\251' -> nc := 4 (* expect 4 continuation bytes *)
- | '\252'..'\253' -> nc := 5 (* expect 5 continuation bytes *)
- | '\254'..'\255' -> nc := 0 (* invalid byte *)
+ | '\248'..'\255' -> nc := 0 (* invalid byte *)
end ;
incr p ;
while !p < len && !nc > 0 do
@@ -299,9 +330,7 @@ let utf8_sub s start_u len_u =
| '\192'..'\223' -> nc := 1 (* expect 1 continuation byte *)
| '\224'..'\239' -> nc := 2 (* expect 2 continuation bytes *)
| '\240'..'\247' -> nc := 3 (* expect 3 continuation bytes *)
- | '\248'..'\251' -> nc := 4 (* expect 4 continuation bytes *)
- | '\252'..'\253' -> nc := 5 (* expect 5 continuation bytes *)
- | '\254'..'\255' -> nc := 0 (* invalid byte *)
+ | '\248'..'\255' -> nc := 0 (* invalid byte *)
end ;
incr p ;
while !p < len_b && !nc > 0 do
diff --git a/lib/unicode.mli b/lib/unicode.mli
index c7d742480..b8e7c33ad 100644
--- a/lib/unicode.mli
+++ b/lib/unicode.mli
@@ -40,3 +40,6 @@ val utf8_length : string -> int
(** Variant of {!String.sub} for UTF-8 strings. *)
val utf8_sub : string -> int -> int -> string
+
+(** Return a "%XX"-escaped string if it contains non UTF-8 characters. *)
+val escaped_if_non_utf8 : string -> string
diff --git a/lib/util.ml b/lib/util.ml
index 36282b2da..6de012da0 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -171,3 +171,12 @@ let open_utf8_file_in fname =
let s = Bytes.make 3 ' ' in
if input in_chan s 0 3 < 3 || not (is_bom s) then seek_in in_chan 0;
in_chan
+
+(** A trick which can typically be used to store on the fly the
+ computation of values in the "when" clause of a "match" then
+ retrieve the evaluated result in the r.h.s of the clause *)
+
+let set_temporary_memory () =
+ let a = ref None in
+ (fun x -> assert (!a = None); a := Some x; x),
+ (fun () -> match !a with Some x -> x | None -> assert false)
diff --git a/lib/util.mli b/lib/util.mli
index d910e7e28..c54f5825c 100644
--- a/lib/util.mli
+++ b/lib/util.mli
@@ -137,3 +137,8 @@ val sym : ('a, 'b) eq -> ('b, 'a) eq
val open_utf8_file_in : string -> in_channel
(** Open an utf-8 encoded file and skip the byte-order mark if any. *)
+
+val set_temporary_memory : unit -> ('a -> 'a) * (unit -> 'a)
+(** A trick which can typically be used to store on the fly the
+ computation of values in the "when" clause of a "match" then
+ retrieve the evaluated result in the r.h.s of the clause *)