1 (**************************************************************************)
2 (* *)
3 (* OCaml *)
4 (* *)
5 (* Jerome Vouillon, projet Cristal, INRIA Rocquencourt *)
6 (* OCaml port by John Malecki and Xavier Leroy *)
7 (* *)
8 (* Copyright 1996 Institut National de Recherche en Informatique et *)
9 (* en Automatique. *)
10 (* *)
11 (* All rights reserved. This file is distributed under the terms of *)
12 (* the GNU Lesser General Public License version 2.1, with the *)
13 (* special exception on linking described in the file LICENSE. *)
14 (* *)
15 (**************************************************************************)
16
17 (*********************** Basic functions and types *********************)
18
19 (*** Miscellaneous ***)
20 exception Out_of_range
21
22 let nothing _ = ()
23
24 (*** Operations on lists. ***)
25
26 (* Remove an element from a list *)
27 let except e l =
28 let rec except_e = function
29 [] -> []
30 | elem::l -> if e = elem then l else elem::except_e l
31 in except_e l
32
33 (* Position of an element in a list. Head of list has position 0. *)
34 let index a l =
35 let rec index_rec i = function
36 [] -> raise Not_found
37 | b::l -> if a = b then i else index_rec (i + 1) l
38 in index_rec 0 l
39
40 (* Return the `n' first elements of `l' *)
41 (* ### n l -> l' *)
42 let rec list_truncate =
43 fun
44 p0 p1 -> match (p0,p1) with (0, _) -> []
45 | (_, []) -> []
46 | (n, (a::l)) -> a::(list_truncate (n - 1) l)
47
48 (* Separate the `n' first elements of `l' and the others *)
49 (* ### n list -> (first, last) *)
50 let rec list_truncate2 =
51 fun
52 p0 p1 -> match (p0,p1) with (0, l) ->
53 ([], l)
54 | (_, []) ->
55 ([], [])
56 | (n, (a::l)) ->
57 let (first, last) = (list_truncate2 (n - 1) l) in
58 (a::first, last)
59
60 (* Replace x by y in list l *)
61 (* ### x y l -> l' *)
62 let list_replace x y =
63 let rec repl =
64 function
65 [] -> []
66 | a::l ->
67 if a == x then y::l
68 else a::(repl l)
69 in repl
70
71 (*** Operations on strings. ***)
72
73 (* Remove blanks (spaces and tabs) at beginning and end of a string. *)
74 let is_space = function
75 | ' ' | '\t' -> true | _ -> false
76
77 let string_trim s =
78 let l = String.length s and i = ref 0 in
79 while
80 !i < l && is_space (String.get s !i)
81 do
82 incr i
83 done;
84 let j = ref (l - 1) in
85 while
86 !j >= !i && is_space (String.get s !j)
87 do
88 decr j
89 done;
90 String.sub s !i (!j - !i + 1)
91
92 (* isprefix s1 s2 returns true if s1 is a prefix of s2. *)
93
94 let isprefix s1 s2 =
95 let l1 = String.length s1 and l2 = String.length s2 in
96 (l1 = l2 && s1 = s2) || (l1 < l2 && s1 = String.sub s2 0 l1)
97
98
99 (*** I/O channels ***)
100
101 type io_channel = {
102 io_in : in_channel;
103 io_out : out_channel;
104 io_fd : Unix.file_descr
105 }
106
107 let io_channel_of_descr fd = {
108 io_in = Unix.in_channel_of_descr fd;
109 io_out = Unix.out_channel_of_descr fd;
110 io_fd = fd
111 }
112
113 let close_io io_channel =
114 close_out_noerr io_channel.io_out;
115 close_in_noerr io_channel.io_in;
116 ;;
117
118 let std_io = {
119 io_in = stdin;
120 io_out = stdout;
121 io_fd = Unix.stdin
122 }
123