File: otags_misc.ml

package info (click to toggle)
otags 4.05.1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • size: 424 kB
  • ctags: 356
  • sloc: ml: 1,267; sh: 212; makefile: 194
file content (138 lines) | stat: -rw-r--r-- 3,420 bytes parent folder | download
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
(* Otags III
 * 
 * Hendrik Tews Copyright (C) 2010 - 2017
 * 
 * This file is part of "Otags III".
 * 
 * "Otags III" is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * "Otags III" is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License in file COPYING in this or one of the parent
 * directories for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with "Otags III". If not, see
 * <http://www.gnu.org/licenses/>.
 * 
 * some misc functions
 * 
 *)

module U = Unix
module UL = Unix.LargeFile

open Global


let the = function
  | Some x -> x
  | None -> assert false

let option_map f = function
  | None -> ()
  | Some x -> f x

(* return true if s2 is an initial substring of s1 *)
let starts_with s1 s2 =
  let s1_len = String.length s1 in
  let s2_len = String.length s2 in
  if s1_len >= s2_len then
    (String.sub s1 0 s2_len) = s2
  else false


let module_name file_name = 
  let base = Filename.basename file_name in
  let module_name =
    if Filename.check_suffix base ".ml"
    then Filename.chop_suffix base ".ml"
    else if Filename.check_suffix base ".mli"
    then Filename.chop_suffix base ".mli"
    else base
  in
  String.capitalize_ascii module_name


(** Split string [s] at occurrences of [c]. Return the list of (non-zero)
    strings between sequences of [c].

    @param c split character
    @param s string to split
*)
let string_split c s =
  let len = String.length s in
  let rec iter i res =
    if i >= len 
    then List.rev res
    else
      let j =
	try String.index_from s i c 
	with Not_found -> len
      in
      iter (j + 1)
	(if i = j then res
	 else (String.sub s i (j - i)) :: res)
  in
  iter 0 []


(** Strip spaces and tabs at start and end of the argument. *)
let strip_white_space s =
  let len = String.length s in
  let i = ref 0 in
  while !i < len && (s.[!i] = ' ' || s.[!i] = '\t') do
    incr i
  done;
  let j = ref (len - 1) in
  while !j >= !i && (s.[!j] = ' ' || s.[!j] = '\t') do
    decr j
  done;
  String.sub s !i (!j - !i + 1)


(* cut_out in_channel start end 
 * cuts the string from start - end out of in_channel
 *)
let cut_out inc start_pos end_pos =
  (* 
   * 3.11 FIX
   * work around out-of-file end positions in 3.11
   * this is fixed in 3.12
   * let end_pos = min end_pos (in_channel_length inc) in
   *)
  seek_in inc start_pos;
  really_input_string inc (end_pos - start_pos)


let input_line_at ic pos =
  seek_in ic pos;
  input_line ic



exception Skip_entry


(** Check whether the first argument is a directory. Raise
    {!Skip_entry} for errors. Errors are reported if the second argument
    is true and depending on {!Global.silent} and {!Global.verbose}.
*)
let is_directory f explicitly_listed =
  try
    (UL.stat f).UL.st_kind = U.S_DIR
  with
    | U.Unix_error(error, _, _) ->
      if explicitly_listed && (not !silent) || !verbose then
	Printf.eprintf "stat failure on %s: %s\n"
	  f
	  (U.error_message error);
      exit_status := 1;
      raise Skip_entry


let file_of_loc loc = loc.Location.loc_start.Lexing.pos_fname