Skip to content

Commit

Permalink
Revise Windows implementation of splitdrive (JuliaLang#42204)
Browse files Browse the repository at this point in the history
This PR makes three improvements to the Windows `splitdrive`
implementation:

1. The matched regex is split into pieces and annotated.
2. Forward and backward slashes are considered equivalent. This fixes
   JuliaLang#38492.
3. The patterns in the regex are reordered so that long UNC paths and
   long drive letters are once more recognized. This has been broken
   since JuliaLang#19695 (Julia 0.5).

Co-authored-by: Jameson Nash <[email protected]>
  • Loading branch information
GunnarFarneback and vtjnash authored Nov 3, 2023
1 parent 746cfdf commit 09cbae8
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion base/path.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,25 @@ elseif Sys.iswindows()
const path_dir_splitter = r"^(.*?)([/\\]+)([^/\\]*)$"sa
const path_ext_splitter = r"^((?:.*[/\\])?(?:\.|[^/\\\.])[^/\\]*?)(\.[^/\\\.]*|)$"sa

const splitdrive_re = let
# Slash in either direction.
S = raw"[\\/]"
# Not a slash in either direction.
N = raw"[^\\/]"
# Drive letter, e.g. `C:`
drive = "$(N)+:"
# UNC path, e.g. `\\server\share`
unc = "$(S)$(S)$(N)+$(S)$(N)+"
# Long drive letter, e.g. `\\?\C:`
long_drive = "$(S)$(S)\\?$(S)$(drive)"
# Long UNC path, e.g. `\\?\UNC\server\share`
long_unc = "$(S)$(S)\\?$(S)UNC$(S)$(N)+$(S)$(N)+"
# Need to match the long patterns first so they get priority.
Regex("^($long_unc|$long_drive|$unc|$drive|)(.*)\$", "sa")
end

function splitdrive(path::String)
m = match(r"^([^\\]+:|\\\\[^\\]+\\[^\\]+|\\\\\?\\UNC\\[^\\]+\\[^\\]+|\\\\\?\\[^\\]+:|)(.*)$"sa, path)::AbstractMatch
m = match(splitdrive_re, path)::AbstractMatch
String(something(m.captures[1])), String(something(m.captures[2]))
end
else
Expand Down

0 comments on commit 09cbae8

Please sign in to comment.