16 |
|
|
17 |
val native : { context: t, spec: string } -> t |
val native : { context: t, spec: string } -> t |
18 |
val standard : { context: t, spec: string } -> t |
val standard : { context: t, spec: string } -> t |
19 |
|
|
20 |
|
val joinDirFile : { dir: t, file: string } -> t |
21 |
|
val splitDirFile : t -> { dir: t, file: string } |
22 |
|
val dir : t -> t |
23 |
|
val file : t -> string |
24 |
end |
end |
25 |
|
|
26 |
structure AbsPath :> ABSPATH = struct |
structure AbsPath :> ABSPATH = struct |
154 |
(* compare pathnames efficiently *) |
(* compare pathnames efficiently *) |
155 |
fun compare (p1, p2) = compareId (id p1, id p2) |
fun compare (p1, p2) = compareId (id p1, id p2) |
156 |
|
|
157 |
(* make an abstract path from a native string *) |
fun fresh (context, spec) = |
|
fun native { spec, context } = |
|
158 |
SPEC { context = context, spec = spec, cache = ref NONE } |
SPEC { context = context, spec = spec, cache = ref NONE } |
159 |
|
|
160 |
|
(* make an abstract path from a native string *) |
161 |
|
fun native { spec, context } = fresh (context, spec) |
162 |
|
|
163 |
(* make an abstract path from a standard string *) |
(* make an abstract path from a standard string *) |
164 |
fun standard { spec, context } = let |
fun standard { spec, context } = let |
165 |
fun delim #"/" = true |
fun delim #"/" = true |
171 |
| transl arc = arc |
| transl arc = arc |
172 |
|
|
173 |
fun mk (isAbs, arcs, context) = |
fun mk (isAbs, arcs, context) = |
174 |
SPEC { context = context, |
fresh (context, |
175 |
spec = P.toString { isAbs = isAbs, vol = "", |
P.toString { isAbs = isAbs, vol = "", |
176 |
arcs = map transl arcs }, |
arcs = map transl arcs }) |
|
cache = ref NONE } |
|
177 |
in |
in |
178 |
case String.fields delim spec of |
case String.fields delim spec of |
179 |
"" :: arcs => mk (true, arcs, context) |
"" :: arcs => mk (true, arcs, context) |
189 |
mk (false, arcn, anchorcontext) |
mk (false, arcn, anchorcontext) |
190 |
end) |
end) |
191 |
end |
end |
192 |
|
|
193 |
|
fun joinDirFile { dir as (CUR _ | CONFIG_ANCHOR _), file } = |
194 |
|
fresh (dir, file) |
195 |
|
| joinDirFile { dir = SPEC { context, spec, ... }, file } = let |
196 |
|
val j = |
197 |
|
P.mkCanonical (P.joinDirFile { dir = spec, file = file }) |
198 |
|
in |
199 |
|
fresh (context, j) |
200 |
|
end |
201 |
|
|
202 |
|
(* The cases where we try to split CUR, CONFIG_ANCHOR, ".", |
203 |
|
* or any path ending in ".." should never occur in practice. |
204 |
|
* It would perhaps be better to put error-handling here... *) |
205 |
|
fun splitDirFile (x as (CUR _ | CONFIG_ANCHOR _)) = |
206 |
|
{ dir = x, file = P.currentArc } |
207 |
|
| splitDirFile (SPEC { context, spec, ... }) = let |
208 |
|
val { dir, file } = P.splitDirFile spec |
209 |
|
val dir = if dir = "" then P.currentArc else dir |
210 |
|
in |
211 |
|
{ dir = fresh (context, dir), file = file } |
212 |
|
end |
213 |
|
|
214 |
|
val dir = #dir o splitDirFile |
215 |
|
val file = #file o splitDirFile |
216 |
end |
end |
217 |
end |
end |