Skip to content

Commit

Permalink
Expose the Win32 logic in OpamStd.Sys.split_path
Browse files Browse the repository at this point in the history
Expose a generalised version of the Windows implementation of
PATH-splitting as OpamStd.String.split_quoted.
  • Loading branch information
dra27 committed May 14, 2024
1 parent 109db24 commit 6a02e09
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 18 deletions.
1 change: 1 addition & 0 deletions master_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,4 @@ users)
## opam-format

## opam-core
* `OpamStd.String`: add `split_quoted` that preserves quoted separator [#5935 @dra27]
40 changes: 22 additions & 18 deletions src/core/opamStd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,26 @@ module OpamString = struct
|_ -> []
in List.rev (aux acc0 tokens)

let split_quoted path sep =
let length = String.length path in
let rec f acc index current last normal =
if (index : int) = length then
let current = current ^ String.sub path last (index - last) in
List.rev (if current <> "" then current::acc else acc)
else
let c = path.[index]
and next = succ index in
if c = sep && normal || c = '"' then
let current = current ^ String.sub path last (index - last) in
if c = '"' then
f acc next current next (not normal)
else
let acc = if current = "" then acc else current::acc in
f acc next "" next true
else
f acc next current last normal in
f [] 0 "" 0 true

let fold_left f acc s =
let acc = ref acc in
for i = 0 to String.length s - 1 do acc := f !acc s.[i] done;
Expand Down Expand Up @@ -877,24 +897,8 @@ module OpamSys = struct
let path_sep = if Sys.win32 then ';' else ':'

let split_path_variable ?(clean=true) =
if Sys.win32 then fun path ->
let length = String.length path in
let rec f acc index current last normal =
if index = length then
let current = current ^ String.sub path last (index - last) in
List.rev (if current <> "" then current::acc else acc)
else let c = path.[index]
and next = succ index in
if c = ';' && normal || c = '"' then
let current = current ^ String.sub path last (index - last) in
if c = '"' then
f acc next current next (not normal)
else
let acc = if current = "" then acc else current::acc in
f acc next "" next true
else
f acc next current last normal in
f [] 0 "" 0 true
if Sys.win32 then
fun path -> OpamString.split_quoted path ';'
else fun path ->
let split = if clean then OpamString.split else OpamString.split_delim in
split path path_sep
Expand Down
6 changes: 6 additions & 0 deletions src/core/opamStd.mli
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,12 @@ module String : sig
contiguous delimiters) *)
val split_delim: string -> char -> string list

(** Splits a variable at the given character, but allowing double-quote
characters to protect the delimiter.
[split_quoted "foo\";\"bar;baz" ';' = ["foo;bar"; "baz"]] *)
val split_quoted: string -> char -> string list

val fold_left: ('a -> char -> 'a) -> 'a -> string -> 'a

val is_hex: string -> bool
Expand Down

0 comments on commit 6a02e09

Please sign in to comment.