package piqilib

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file piqi_file.ml

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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
(*
   Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2017 Anton Lavrik

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*)


open Piqi_common


let chop_extension fname =
  try Filename.chop_extension fname
  with _ -> fname


let chop_all_extensions fname =
  let start =
    try (String.rindex fname '/') + 1
    with Not_found -> 0
  in
  try 
    let i = String.index_from fname start '.' in
    String.sub fname 0 i
  with Not_found -> fname


let chop_piqi_extensions fname =
  if Filename.check_suffix fname ".proto.piqi"
  then Filename.chop_suffix fname ".proto.piqi"
  else
    if Filename.check_suffix fname ".piqi"
    then Filename.chop_suffix fname ".piqi"
    else fname


(* basename + chop .piqi and .proto.piqi extensions *)
let basename filename =
  let basename = Filename.basename filename in
  chop_piqi_extensions basename


let dirname = Filename.dirname


let concat = Filename.concat


let get_extension s =
  try
    let pos = String.rindex s '.' in
    String.sub s (pos + 1) (String.length s - pos - 1)
  with
    Not_found -> ""


(* reverts slashes on Windows *)
let make_os_path name =
  match Sys.os_type with
    | "Win32" ->
        U.string_subst_char name '/' '\\'
    | _ -> name


(* find piqi file in search paths given its (relative) split name *)
let find_piqi_file ?(extra_paths=[]) modname =
  let dir_name, base_name = Piqi_name.split_name modname in
  let dir_name =
    match dir_name with
      | None -> ""
      | Some x -> make_os_path x (* reverse slashes on Windows *)
  in
  let found_dir = ref "" and found_name = ref "" (* results references *)
  in
  let check_exact_file dir_name base_name ext =
    let file_name = Filename.concat dir_name base_name ^ ext in
    let full_file_path = Filename.concat !found_dir file_name in
    trace "trying to locate module at %s\n" (U.quote full_file_path);
    if Sys.file_exists full_file_path
    then (found_name := file_name; true)
    else false
  in
  let check_file dir_name ext =
    (* try to find the exact match first *)
    if check_exact_file dir_name base_name ext
    then true
    else
      (* flip underscores to dashes or the other way around and try again
       * (modnames can't contain both underscores and dashes at the same time)
       *)
      if String.contains base_name '_'
      then
        let base_name = U.underscores_to_dashes base_name in
        check_exact_file dir_name base_name ext
      else if String.contains base_name '-'
      then
        let base_name = U.dashes_to_underscores base_name in
        check_exact_file dir_name base_name ext
      else false
  in
  let check_exact_directory base_dir dir_name =
    let dir = Filename.concat base_dir dir_name in
    trace "trying to locate module directory at %s\n" (U.quote dir);
    let directory_exists =
      if Sys.os_type = "Unix"
      then
        try Sys.is_directory dir with Sys_error _ -> false
      else
        (* for some reason, the above method doesn't work for mingw-based builds
         * when they are called from cygwin environment *)
        true
    in
    if directory_exists then found_dir := base_dir;
    directory_exists
  in
  let find_directory base_dir =
    if check_exact_directory base_dir dir_name
    then Some dir_name
    else
      (* if there's no exact directory, handle handle directory normalization
       * when all '_' are converted to '-':  change underscores to dashes and
       * try again *)
      if String.contains dir_name '_'
      then
        let dir_name = U.underscores_to_dashes dir_name in
        if check_exact_directory base_dir dir_name
        then Some dir_name
        else None
      else None
  in
  let find_file base_dir =
    match find_directory base_dir with
      | None -> false
      | Some dir_name ->
          List.exists (fun ext -> check_file dir_name ext) [".piqi"; ".proto.piqi"]
  in
  if List.exists find_file (extra_paths @ !Piqi_config.paths)
  then
    !found_dir, !found_name
  else
    (trace "piqi module is not found in path: %s\n" (U.quote modname);
     raise Not_found
    )


let find_piqi modname =
  (* NOTE: now supporting only local namespace *)
  let dir, fname = find_piqi_file modname in
  Filename.concat dir fname