File: utils.ml

package info (click to toggle)
camlidl 1.12-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,592 kB
  • sloc: ml: 5,238; ansic: 945; cpp: 908; makefile: 358; xml: 213; sh: 74
file content (111 lines) | stat: -rw-r--r-- 3,152 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
(***********************************************************************)
(*                                                                     *)
(*                              CamlIDL                                *)
(*                                                                     *)
(*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         *)
(*                                                                     *)
(*  Copyright 1999 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  under the terms of the GNU Lesser General Public License LGPL v2.1 *)
(*                                                                     *)
(***********************************************************************)

(* $Id: utils.ml,v 1.11 2002-01-16 16:15:34 xleroy Exp $ *)

(* Utility functions *)

open Printf

(* Indented printf *)

let current_indentation = ref 0

let iprintf oc fmt =
  for i = 1 to !current_indentation do output_char oc ' ' done;
  fprintf oc fmt

let increase_indent() =
  current_indentation := !current_indentation + 2

let decrease_indent() =
  current_indentation := !current_indentation - 2

(* Remove a file, ignoring errors *)

let remove_file name =
  try Sys.remove name with Sys_error _ -> ()

(* Divert output to a temp file *)

let temp_file = ref ""
let temp_out = ref stdout

let divert_output() =
  let f = Filename.temp_file "camlidl" ".c" in
  let oc = open_out f in
  temp_file := f; temp_out := oc; oc

let end_diversion oc =
  close_out !temp_out;
  let ic = open_in !temp_file in
  let buffer = Bytes.create 256 in
  let rec copy() =
    let n = input ic buffer 0 256 in
    if n > 0 then (output oc buffer 0 n; copy()) in
  copy();
  close_in ic;
  remove_file !temp_file

(* Remember current module name and current function name *)

let module_name = ref "Mod"
let current_function = ref ""

(* Emit error messages *)

exception Error

let error msg =
  eprintf "%s.idl" !module_name;
  if !current_function <> "" then eprintf ", function %s" !current_function;
  eprintf ": %s\n" msg;
  raise Error

(* List hacking *)

let rec list_filter pred = function
    [] -> []
  | hd :: tl ->
      if pred hd then hd :: list_filter pred tl else list_filter pred tl

let rec list_partition pred = function
    [] -> ([], [])
  | hd :: tl ->
      let (p1, p2) = list_partition pred tl in
      if pred hd then (hd :: p1, p2) else (p1, hd :: p2)

let rec map_index f i = function
    [] -> []
  | hd :: tl -> f i hd :: map_index f (i + 1) tl

let rec iter_index f i = function
    [] -> ()
  | hd :: tl -> f i hd; iter_index f (i + 1) tl

(* Path searching *)

let find_in_path path name =
  if not (Filename.is_implicit name) then
    if Sys.file_exists name then name else raise Not_found
  else begin
    let rec try_dir = function
      [] -> raise Not_found
    | dir::rem ->
        let fullname = Filename.concat dir name in
        if Sys.file_exists fullname then fullname else try_dir rem
    in try_dir path
  end

(* Discard result *)

(*external ignore: 'a -> unit = "%identity" (* not quite *)*)