|
rpm-build |
0f2925 |
(*
|
|
rpm-build |
0f2925 |
* Std - Additional functions
|
|
rpm-build |
0f2925 |
* Copyright (C) 2003 Nicolas Cannasse and Markus Mottl
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* This library is free software; you can redistribute it and/or
|
|
rpm-build |
0f2925 |
* modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0f2925 |
* License as published by the Free Software Foundation; either
|
|
rpm-build |
0f2925 |
* version 2.1 of the License, or (at your option) any later version,
|
|
rpm-build |
0f2925 |
* with the special exception on linking described in file LICENSE.
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
0f2925 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0f2925 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0f2925 |
* Lesser General Public License for more details.
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0f2925 |
* License along with this library; if not, write to the Free Software
|
|
rpm-build |
0f2925 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
rpm-build |
0f2925 |
*)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
open ExtBytes
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let finally handler f x =
|
|
rpm-build |
0f2925 |
let r = (
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
f x
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
e -> handler (); raise e
|
|
rpm-build |
0f2925 |
) in
|
|
rpm-build |
0f2925 |
handler ();
|
|
rpm-build |
0f2925 |
r
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_lines ch =
|
|
rpm-build |
0f2925 |
Enum.from (fun () ->
|
|
rpm-build |
0f2925 |
try input_line ch with End_of_file -> raise Enum.No_more_elements)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_chars ch =
|
|
rpm-build |
0f2925 |
Enum.from (fun () ->
|
|
rpm-build |
0f2925 |
try input_char ch with End_of_file -> raise Enum.No_more_elements)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type 'a _mut_list = {
|
|
rpm-build |
0f2925 |
hd : 'a;
|
|
rpm-build |
0f2925 |
mutable tl : 'a _mut_list;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_list ch =
|
|
rpm-build |
0f2925 |
let _empty = Obj.magic [] in
|
|
rpm-build |
0f2925 |
let rec loop dst =
|
|
rpm-build |
0f2925 |
let r = { hd = input_line ch; tl = _empty } in
|
|
rpm-build |
0f2925 |
dst.tl <- r;
|
|
rpm-build |
0f2925 |
loop r in
|
|
rpm-build |
0f2925 |
let r = { hd = Obj.magic(); tl = _empty } in
|
|
rpm-build |
0f2925 |
try loop r
|
|
rpm-build |
0f2925 |
with
|
|
rpm-build |
0f2925 |
End_of_file ->
|
|
rpm-build |
0f2925 |
Obj.magic r.tl
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let buf_len = 8192
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_all ic =
|
|
rpm-build |
0f2925 |
let rec loop acc total buf ofs =
|
|
rpm-build |
0f2925 |
let n = input ic buf ofs (buf_len - ofs) in
|
|
rpm-build |
0f2925 |
if n = 0 then
|
|
rpm-build |
0f2925 |
let res = Bytes.create total in
|
|
rpm-build |
0f2925 |
let pos = total - ofs in
|
|
rpm-build |
0f2925 |
let _ = Bytes.blit buf 0 res pos ofs in
|
|
rpm-build |
0f2925 |
let coll pos buf =
|
|
rpm-build |
0f2925 |
let new_pos = pos - buf_len in
|
|
rpm-build |
0f2925 |
Bytes.blit buf 0 res new_pos buf_len;
|
|
rpm-build |
0f2925 |
new_pos in
|
|
rpm-build |
0f2925 |
let _ = List.fold_left coll pos acc in
|
|
rpm-build |
0f2925 |
(* [res] doesn't escape and will not be mutated again *)
|
|
rpm-build |
0f2925 |
Bytes.unsafe_to_string res
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
let new_ofs = ofs + n in
|
|
rpm-build |
0f2925 |
let new_total = total + n in
|
|
rpm-build |
0f2925 |
if new_ofs = buf_len then
|
|
rpm-build |
0f2925 |
loop (buf :: acc) new_total (Bytes.create buf_len) 0
|
|
rpm-build |
0f2925 |
else loop acc new_total buf new_ofs in
|
|
rpm-build |
0f2925 |
loop [] 0 (Bytes.create buf_len) 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let input_file ?(bin=false) fname =
|
|
rpm-build |
0f2925 |
let ch = (if bin then open_in_bin else open_in) fname in
|
|
rpm-build |
0f2925 |
finally (fun () -> close_in ch) input_all ch
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let output_file ~filename ~text =
|
|
rpm-build |
0f2925 |
let ch = open_out filename in
|
|
rpm-build |
0f2925 |
finally (fun () -> close_out ch) (output_string ch) text
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let print_bool = function
|
|
rpm-build |
0f2925 |
| true -> print_string "true"
|
|
rpm-build |
0f2925 |
| false -> print_string "false"
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let prerr_bool = function
|
|
rpm-build |
0f2925 |
| true -> prerr_string "true"
|
|
rpm-build |
0f2925 |
| false -> prerr_string "false"
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let string_of_char c = String.make 1 c
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
external identity : 'a -> 'a = "%identity"
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let rec dump r =
|
|
rpm-build |
0f2925 |
if Obj.is_int r then
|
|
rpm-build |
0f2925 |
string_of_int (Obj.magic r : int)
|
|
rpm-build |
0f2925 |
else (* Block. *)
|
|
rpm-build |
0f2925 |
let rec get_fields acc = function
|
|
rpm-build |
0f2925 |
| 0 -> acc
|
|
rpm-build |
0f2925 |
| n -> let n = n-1 in get_fields (Obj.field r n :: acc) n
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let rec is_list r =
|
|
rpm-build |
0f2925 |
if Obj.is_int r then
|
|
rpm-build |
0f2925 |
r = Obj.repr 0 (* [] *)
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
let s = Obj.size r and t = Obj.tag r in
|
|
rpm-build |
0f2925 |
t = 0 && s = 2 && is_list (Obj.field r 1) (* h :: t *)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let rec get_list r =
|
|
rpm-build |
0f2925 |
if Obj.is_int r then
|
|
rpm-build |
0f2925 |
[]
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
let h = Obj.field r 0 and t = get_list (Obj.field r 1) in
|
|
rpm-build |
0f2925 |
h :: t
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let opaque name =
|
|
rpm-build |
0f2925 |
(* XXX In future, print the address of value 'r'. Not possible in
|
|
rpm-build |
0f2925 |
* pure OCaml at the moment.
|
|
rpm-build |
0f2925 |
*)
|
|
rpm-build |
0f2925 |
"<" ^ name ^ ">"
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let s = Obj.size r and t = Obj.tag r in
|
|
rpm-build |
0f2925 |
(* From the tag, determine the type of block. *)
|
|
rpm-build |
0f2925 |
match t with
|
|
rpm-build |
0f2925 |
| _ when is_list r ->
|
|
rpm-build |
0f2925 |
let fields = get_list r in
|
|
rpm-build |
0f2925 |
"[" ^ String.concat "; " (List.map dump fields) ^ "]"
|
|
rpm-build |
0f2925 |
| 0 ->
|
|
rpm-build |
0f2925 |
let fields = get_fields [] s in
|
|
rpm-build |
0f2925 |
"(" ^ String.concat ", " (List.map dump fields) ^ ")"
|
|
rpm-build |
0f2925 |
| x when x = Obj.lazy_tag ->
|
|
rpm-build |
0f2925 |
(* Note that [lazy_tag .. forward_tag] are < no_scan_tag. Not
|
|
rpm-build |
0f2925 |
* clear if very large constructed values could have the same
|
|
rpm-build |
0f2925 |
* tag. XXX *)
|
|
rpm-build |
0f2925 |
opaque "lazy"
|
|
rpm-build |
0f2925 |
| x when x = Obj.closure_tag ->
|
|
rpm-build |
0f2925 |
opaque "closure"
|
|
rpm-build |
0f2925 |
| x when x = Obj.object_tag ->
|
|
rpm-build |
0f2925 |
let fields = get_fields [] s in
|
|
rpm-build |
0f2925 |
let clasz, id, slots =
|
|
rpm-build |
0f2925 |
match fields with
|
|
rpm-build |
0f2925 |
| h::h'::t -> h, h', t
|
|
rpm-build |
0f2925 |
| _ -> assert false
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
(* No information on decoding the class (first field). So just print
|
|
rpm-build |
0f2925 |
* out the ID and the slots. *)
|
|
rpm-build |
0f2925 |
"Object #" ^ dump id ^ " (" ^ String.concat ", " (List.map dump slots) ^ ")"
|
|
rpm-build |
0f2925 |
| x when x = Obj.infix_tag ->
|
|
rpm-build |
0f2925 |
opaque "infix"
|
|
rpm-build |
0f2925 |
| x when x = Obj.forward_tag ->
|
|
rpm-build |
0f2925 |
opaque "forward"
|
|
rpm-build |
0f2925 |
| x when x < Obj.no_scan_tag ->
|
|
rpm-build |
0f2925 |
let fields = get_fields [] s in
|
|
rpm-build |
0f2925 |
"Tag" ^ string_of_int t ^
|
|
rpm-build |
0f2925 |
" (" ^ String.concat ", " (List.map dump fields) ^ ")"
|
|
rpm-build |
0f2925 |
| x when x = Obj.string_tag ->
|
|
rpm-build |
0f2925 |
"\"" ^ String.escaped (Obj.magic r : string) ^ "\""
|
|
rpm-build |
0f2925 |
| x when x = Obj.double_tag ->
|
|
rpm-build |
0f2925 |
string_of_float (Obj.magic r : float)
|
|
rpm-build |
0f2925 |
| x when x = Obj.abstract_tag ->
|
|
rpm-build |
0f2925 |
opaque "abstract"
|
|
rpm-build |
0f2925 |
| x when x = Obj.custom_tag ->
|
|
rpm-build |
0f2925 |
opaque "custom"
|
|
rpm-build |
0f2925 |
| x when x = Obj.double_array_tag ->
|
|
rpm-build |
0f2925 |
let l = ExtList.List.init s (fun i -> string_of_float (Obj.double_field r i)) in
|
|
rpm-build |
0f2925 |
"[| " ^ String.concat "; " l ^ " |]"
|
|
rpm-build |
0f2925 |
| _ ->
|
|
rpm-build |
0f2925 |
opaque (Printf.sprintf "unknown: tag %d size %d" t s)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let dump v = dump (Obj.repr v)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let print v = print_endline (dump v)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let __unique_counter = ref 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let unique () =
|
|
rpm-build |
0f2925 |
incr __unique_counter;
|
|
rpm-build |
0f2925 |
!__unique_counter
|