Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions src/fname.ml
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,25 @@ let parse s =
let parse_git_header s =
let parse s =
match parse_filename ~allow_space:true s with
| Ok (s, "") -> Ok (Lib.String.cut '/' s)
| Ok (s, "") ->
begin match String.index_opt s '/' with
| Some i -> Ok (Lib.String.slice ~start:(i + 1) s)
| None -> Error "Slash not found"
end
| Ok _ -> Error "Unexpected character after closing double-quote in header"
| Error _ as err -> err
in
let rec loop s len i =
if i < len then
if i < (len : int) then
match s.[i] with
| ' ' | '\t' ->
let a = parse (Lib.String.slice ~stop:i s) in
let b = parse (Lib.String.slice ~start:(i + 1) s) in
begin match a, b with
| Ok (Some ("a", a)), Ok (Some ("b", b))
when a = (b : string) ->
Some a
| _, _ -> loop s len (i + 1)
begin match parse (Lib.String.slice ~stop:i s) with
| Ok a ->
begin match parse (Lib.String.slice ~start:(i + 1) s) with
| Ok b when a = (b : string) -> Some a
| _ -> loop s len (i + 1)
end
| Error _ -> loop s len (i + 1)
end
| _ -> loop s len (i + 1)
else
Expand Down
80 changes: 48 additions & 32 deletions src/lib.ml
Original file line number Diff line number Diff line change
@@ -1,35 +1,48 @@
module String = struct
let is_prefix ~prefix str =
let pl = String.length prefix in
if String.length str < pl then
false
else
String.sub str 0 (String.length prefix) = prefix
let is_prefix =
let rec aux i ~prefix_len ~prefix ~str =
if i < (prefix_len : int) then
if String.unsafe_get str i =
(String.unsafe_get prefix i : char) then
aux (i + 1) ~prefix_len ~prefix ~str
else
false
else
true
in
fun ~prefix str ->
let prefix_len = String.length prefix in
if prefix_len <= (String.length str : int) then
aux 0 ~prefix_len ~prefix ~str
else
false

let is_suffix ~suffix str =
let pl = String.length suffix in
if String.length str < pl then
false
else
String.sub str (String.length str - pl) pl = suffix
let is_suffix =
let rec aux suffix_i str_i ~suffix_len ~suffix ~str =
if suffix_i < (suffix_len : int) then
if String.unsafe_get str str_i =
(String.unsafe_get suffix suffix_i : char) then
aux (suffix_i + 1) (str_i + 1) ~suffix_len ~suffix ~str
else
false
else
true
in
fun ~suffix str ->
let suffix_len = String.length suffix in
let str_len = String.length str in
if suffix_len <= (str_len : int) then
aux 0 (str_len - suffix_len) ~suffix_len ~suffix ~str
else
false

let cut sep str =
try
let idx = String.index str sep
and l = String.length str
in
let sidx = succ idx in
Some (String.sub str 0 idx, String.sub str sidx (l - sidx))
with
Not_found -> None

let cuts sep str =
let rec doit acc s =
match cut sep s with
| None -> List.rev (s :: acc)
| Some (a, b) -> doit (a :: acc) b
in
doit [] str
match String.index_opt str sep with
| Some idx ->
let l = String.length str in
let sidx = idx + 1 in
Some (String.sub str 0 idx, String.sub str sidx (l - sidx))
| None -> None

let slice ?(start = 0) ?stop str =
let stop = match stop with
Expand All @@ -41,8 +54,11 @@ module String = struct
end

module List = struct
let rec last = function
| [] -> invalid_arg "List.last"
| [x] -> x
| _::xs -> last xs
let rev_cut idx l =
let rec aux acc idx = function
| l when idx = 0 -> (acc, l)
| [] -> invalid_arg "List.cut"
| x::xs -> aux (x :: acc) (idx - 1) xs
in
aux [] idx l
end
3 changes: 1 addition & 2 deletions src/lib.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ module String : sig
val is_prefix : prefix:string -> string -> bool
val is_suffix : suffix:string -> string -> bool
val cut : char -> string -> (string * string) option
val cuts : char -> string -> string list
val slice : ?start:int -> ?stop:int -> string -> string
end

module List : sig
val last : 'a list -> 'a
val rev_cut : int -> 'a list -> 'a list * 'a list
end
Loading